Fórum témák

» Több friss téma
Fórum » Arduino
A klónok CH340 Soros-USB illesztőjének drivere (Letöltés)
Lapozás: OK   94 / 852
(#) erdeidominik1999 hozzászólása Márc 12, 2015 /
 
Sziasztok! Már a múltkor feltettem kérdésnek, hátha valaki tud valami megoldást, hogy van egy megám és elég lassan fut a progi rajta, megnézegettem a problémás részeket, és pl egyik a dht11-es szenzornak az olvasása, ez normális, hogy ilyen lassú? Előre is köszi!
(#) TavIR-AVR válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Az a DHT11 nem fehér tokozású? Mert az DHT22 akkor....
És az 1/2 sebességű, mint a DHT11.
(#) erdeidominik1999 válasza TavIR-AVR hozzászólására (») Márc 12, 2015 /
 
Nem, dht11, de nem csak az okozza a lassúságot, hanem pl. lcd-re kiiratom time könyvtárból a pontos időt, és az is nagyon lassú.
(#) Kovidivi válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Szerintem olyan hosszú az interruptod, vagy olyan sok van belőle, hogy nem marad ideje a Meganak a főprogramot futtatni. Arról nem is beszélve, hogy egy digitalwrite() függvény meghív meg további függvényeket, az ADC beolvasása sem éppen gyors, ezeket érdemes lenne átirni rendes AVR kódokra, mint PORTD=stb.
A hozzászólás módosítva: Márc 12, 2015
(#) kapu48 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
A kód ismerete nélkül csak lottózni lehet! (Azt meg ügye nehéz eltalálni!)
(#) erdeidominik1999 válasza kapu48 hozzászólására (») Márc 12, 2015 /
 
Itt a komplett kód! Van egy olyan rész, hogy homero() abban van a dht11-es olvasás.
A hozzászólás módosítva: Márc 12, 2015
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Huhh, felteszem a kérdést. Mitől lenne gyors?

Őrült mennyiségű serial kiírás (legalább emelnéd meg a bitrátát mondjuk 115200-ra, azt ugye tudod, hogy minden karakter kiíratása majdnem 1ms-be kerül most? te meg regényeket írsz ki).

Használsz egy csomó delay-t (ilyenkor az uC-d nem csinál semmi hasznosat). Old meg időzítő megszakítással vagy millis-el.

Rengeteg vizsgálatot végzel el minden egyes ciklusban. Kérdem, minek? Ha az időt csak perc pontossággal dolgozod fel, minek állandóan lekérdezni (időzítő megszakítás)? Ha elég lenne az eseményeket akkor vizsgálni ha változott is valami, akkor minek állandóan nézni (PCINT megszakítások)?

EEPROM kezelés (haragszol az EEPROM-odra? ), tegyél fel egy Save gombot és csak akkor mentsd el a paramétereket ha tényleg kell (előtte olvasd ki a byte-ot, hogy tényleg változott-e).

A kód amúgy szinte olvashatatlan. Rengeteg ismétlés (szervezd ki függvénybe, esetleg inline is lehet).
(#) erdeidominik1999 válasza csatti2 hozzászólására (») Márc 12, 2015 /
 
A serial csak akkor ír, ha megnyitom a webes felületet, a delay is csak akor van, ha egy zóna iktatva van, alapból a delayt kihagyja, az idővel és az eeprommal kapcsolatban nem igazán értem.
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Az időnél azt az if (evbeallitasa1 == false && evbeallitasa2 == false & stb. részt értem. Arra például mi szükség minden egyes ciklusban? Persze kiemelhettem volna még hasonlókat.

Az EEPROM nem örök életű, azt ugye tudod. Meghatározott számban írhatod, utána vége. Épp ezért illik vigyázni rá, csak akkor írni ha tényleg kell. Ha előtte beolvasod az aktuális tartalmát és összehasonlítod azzal, amit oda írni szeretnél akkor gyakran spórolhatsz egy ciklust. Ha jól értem, amit csináltál, akkor most minden egyes alkalommal, amikor vki átnyom egy beállítást akkor menti az EEPROM-ba. Csinálsz egy apró hibát vhol a webkódban, esetleg rászabadul egy crawler bot, vagy akármi más és kinyírja most az EEPROM-odat.
(#) erdeidominik1999 válasza csatti2 hozzászólására (») Márc 12, 2015 /
 
Értem, köszi, az EEPROM-ot meg fogom csinálni, és átnézem, amit előzőekben írtál, az valóban kerülhetne máshova...
(#) erdeidominik1999 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Még annyi kérdésem lenne, hogy ha pl a hónapot a napot meg az órát, esetleg a percet berakom egy változóba, és megnézem, hogy az aktuális nagyobb-e mint a változó, és csak akkor iratom lcd-re, ha negyobb, az számit valamit?
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Minden pici számít. De azért csinálj egy időzítő megszakítást, amivel aszinkron módon aktiválhatod az ilyen jellegű vizsgálatokat.
A bemenetekhez pedig nézd meg a PCINT megszakításokat. Ezek azért jók, mert akkor hívódnak csak meg ha a konfigurált pin-ek értéke változik (minek olvasgasd a lábakat digitalread-al ha úgyse változott?). Ráadásul abban a pillanatban reagálhatsz rá, ahogy valami történt, nemcsak amikor a ciklusban arra került a sor, hogy beolvasd azt a lábat.
(#) erdeidominik1999 válasza csatti2 hozzászólására (») Márc 12, 2015 /
 
Köszi szépen a sok infót!
(#) erdeidominik1999 válasza csatti2 hozzászólására (») Márc 12, 2015 /
 
Ilyen megszakítást találtam, ez jó? Csak az a baj hogy itt muszáj létrehoznom egy void ot minden lábnak.
  1. void setup()
  2. {
  3.   pinMode(13, OUTPUT);
  4.   pinMode(2,INPUT_PULLUP);
  5.   attachInterrupt(0, blink, FALLING);
  6.   Serial.begin(115200);
  7. }
  8.  
  9. void loop()
  10. {
  11.   delay(10000);
  12. }
  13.  
  14. void blink(){
  15. Serial.println("OK");
  16. }
A hozzászólás módosítva: Márc 12, 2015
(#) erdeidominik1999 válasza erdeidominik1999 hozzászólására (») Márc 12, 2015 /
 
Illetve még annyi hogy ha van egy digitalWrite-om, amit mindig csinál, akkor jobban járnék, ha előtte digitalRead-del megnézném a lábat és csak akkor írnék rá, ha változott?
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 13, 2015 / 1
 
Nincs véletlenül egy Arduino UNO-d? Egyszerűbb ha egy kis programon begyakorolod azt a pár példát, amit mutatok és csak utána implementálod a MEGA-ra (ezek a kódok uC függőek lesznek, nem használhatod azt, amit az UNO-ra írtál direktben a MEGA-n!).

A gond az Arduino megszakítás kezelésével, hogy nagyon limitált. Ezért én sosem használom.

Amire szükséged lesz az az UNO és a MEGA 2560 uC-inek kézikönyvei. Ezek első látásra elég rémisztőek lehetnek, de szerencsére szépen fejezetekre bontották a különböző funkciók szerint a leírásokat, így mindig csak pár oldalt kell átnézni. Ha kicsit jobban beleásod magad, láthatod majd milyen sok minden mást is kihozhatsz még a cuccodból.

Hasznos még az alábbi két gyors referencia kép is, ami az UNO és a MEGA lábkiosztását mutatja, a lábak port kiosztásával, illetve egyéb kiegészítő funkcióinak feltüntetésével egyetemben.
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 13, 2015 / 1
 
Az első példa a PCINT megszakításokkal kapcsolatos (Pin Change Interrupt). Adott egy 3 nyomógombból összerakott kezelőfelület és a gombok lenyomását szeretnénk érzékelni.

Előkészület:
Regisztrálunk pár makrót a kód könnyebb olvashatósága érdekében. Ezek a makrók a regiszterek bitjeinek beállítására illetve törlésére valóak.
  1. // Defines for setting and clearing register bits
  2. #ifndef cbi
  3. #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  4. #endif
  5. #ifndef sbi
  6. #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  7. #endif


Első feladat: a megszakítás inicializálása
  1. /**
  2.  * \brief Initializes PCINT2 interrupt for switch press detection
  3.  *
  4.  * \return void
  5.  */
  6. void _initSwitches()
  7. {
  8.         cli();
  9.         //Enable pin change interrupt 2, (PCINT23..16 pins)
  10.         sbi(PCICR,PCIE2);
  11.         //Interrupt mask for switch inputs
  12.         sbi(PCMSK2,PCINT20); //Switch 1, pin 4
  13.         sbi(PCMSK2,PCINT21); //Switch 2, pin 5
  14.         sbi(PCMSK2,PCINT22); //Switch 3, pin 6 
  15.         sei();
  16. }


Mi is történik itt:
A cli() letiltja a megszakításokat, a sei() újra engedélyezi azt.
Fontos tudni, hogy több pin change megszakítás áll rendelkezésre. Például ebben az esetben a D porthoz a PCIE2 tartozik. Mivel az összes vizsgálni kívánt bemenet ehhez a porthoz csatlakozik elég csupán ezt engedélyezni. (12.2.4. fejezet)
Ha megnézed a refernciaképet, láthatod, hogy a 4, 5 és 6 os lábak mellett szerepel a PCINT20, 21 és 22 felirat. Ez alapján tudjuk bebillenteni a maszkban, mely lábak változásakor lépjen működésbe a megszakítás. (12.2.6. fejezet)

Definiáljunk pár változót:
  1. volatile bool _switches[3] = {0};
  2. volatile bool _switchesUsed[3] = {0};
  3. volatile unsigned long _switchAct = 0;
  4. volatile unsigned long _clickNum = 0;


Következő lépés a megszakítás elkészítése:
  1. // Pin change interrupt 2
  2. ISR(PCINT2_vect)
  3. {
  4.         volatile static uint8_t prev_switches = 0;
  5.         unsigned long m = millis();
  6.        
  7.         uint8_t switches = ~PIND & 0x70;  //Switch signals are inverted, masked the switch pins
  8.         uint8_t activated = (switches ^ prev_switches) & switches;
  9.        
  10.         if (activated & 0x10) {
  11.                 _switches[0] = true;
  12.                 _switchAct = m;
  13.                 _clickNum = 0;
  14.         }
  15.         if (activated & 0x20) {
  16.                 _switches[1] = true;
  17.                 _switchAct = m;
  18.                 _clickNum = 0;
  19.         }
  20.         if (activated & 0x40) {
  21.                 _switches[2] = true;
  22.                 _switchAct = m;
  23.                 _clickNum = 0;
  24.         }
  25.        
  26.         if (!(switches & 0x10)) { _switches[0] = false; _switchesUsed[0] = false; }
  27.         if (!(switches & 0x20)) { _switches[1] = false; _switchesUsed[1] = false; }
  28.         if (!(switches & 0x40)) { _switches[2] = false; _switchesUsed[2] = false; }
  29.         prev_switches = switches;
  30. }


Ha megnézed újra a referencia képet, láthatod, hogy a 4, 5 és 6-os lábak mellett a PD4, PD5 és PD6 szerepel. Ez azt jelenti, hogy a lábak a D port 4-es, 5-ös, illetve 6-os bitjeihez vannak rendelve. Tehát egy utasítással beolvasható 8 láb állapota (khm, nem éppen 8 lassú digitalRead ). A PIND utasítás szolgál a D port beolvasására. Előtte negálom, mivel a lábak felhúzó ellenállással 5V-on vannak és csak gomb lenyomásakor lesz az értékük 0-a. Utána pedig a 0x70 maszkkal eldobom az érdektelen biteket (ez itt mondjuk nem fontos).
A következő lépés, hogy megkeresem melyik gomb lett most lenyomva. (switches ^ prev_switches) azokon a biteken ad vissza egyet, ahol változott a bit a korábbi állapothoz képest. (switches ^ prev_switches) & switches végeredménye pedig, hogy csak ott lesz 1, amit most nyomtak le (a felengedések nem érdekesek).
A kód többi részében előállítom a később használandó változók értékét. Azért tűnik komplikáltnak, mert egy egyszeri lenyomást, illetve folyamatos lenyomást egyaránt kezelő a gombokat pergésmentesített kód következik utána.
(#) csatti2 válasza erdeidominik1999 hozzászólására (») Márc 13, 2015 / 1
 
Nézzünk most egy példát időzítőre.
A példában a timer 1 időzítőt fogom használni, ami 16 bites. A cél egy 1280Hz-es analóg mintavételezés indítása.

Első lépés a megszakítás inicializálása.
  1. /**
  2.  * \brief Initialization for timer 1 interrupt used for ADC requests
  3.  *
  4.  * \return void
  5.  */
  6. void _initQueryTimer()
  7. {
  8.         cli();
  9.         //Set Timer1 interrupt to 1280Hz
  10.         TCCR1A = 0;
  11.         TCCR1B = 0;
  12.         TCNT1  = 0;//Counter value to 0
  13.         OCR1A = 12510;// = (16MHz) / ((1280*1) - 1)
  14.         // CTC mode
  15.         sbi(TCCR1B,WGM12);
  16.         // Set CS10 bit for no prescaler
  17.         sbi(TCCR1B,CS10);
  18.         // Enable timer compare A interrupt
  19.         sbi(TIMSK1,OCIE1A);
  20.         sei();
  21. }


A cli utáni első három utasítással alaphelyzetbe állítom az időzítőt. (15.11 alatti fejezetek)
Ezek után meghatározom, milyen gyakran hívódjon meg a megszakítás. A képletben a 16MHz a használt kristály frekvenciájára utal. Ez 16MHz szokott lenni 5V-os arduino-nál. A második rész a kívánt mintavételezési frekvencia szorozva a később beállítandó prescaler értékével. A mínusz egy pedig az azért van, mert 0 esetén is van egy ciklus. Ha a kiszámított érték nagyobb mint 2^16 -1 (65535), akkor növelni kell a prescaler értékét. A lehetséges prescaler beállítások a 15.11.2 alatti 15-5-ös táblázatban találhatóak.
Aktiválom a CTC módot (Clear Timer on Compare). Ez azt jelenti, hogy felszámol a timer 1 0-tól az OCR1A-ban tárolt értékig, majd nulláz és kezdi elölről.
Következő lépésben kikapcsolom a prescaler-t (prescaler = 1, ugye). Majd engedélyezem a megszakítást (15.11.8).

Majd jön a megszakítás:
  1. // Timer 1 comparator A
  2. ISR(TIMER1_COMPA_vect)
  3. {
  4.         // Start ADC conversion
  5.         sbi(ADCSRA, ADSC);
  6. }


A lényeg persze az analóg mintavételezés kész megszakításban lesz itt (semmiféle várakozás az analogRead-re , ráadásul tök pontatlan is ahogy az arduino-ban használják). De ennyi most elég szerintem.
A hozzászólás módosítva: Márc 13, 2015
(#) erdeidominik1999 válasza csatti2 hozzászólására (») Márc 13, 2015 /
 
Nagyon szépen köszi a sok infót!
(#) ISF79 hozzászólása Márc 14, 2015 /
 
Sziasztok!

Ethernet shield SD kártyán lévő index.htm-el szeretnék megjeleníteni egy szintén az SD kártyán lévő x.jpg-t. Viszont a weboldal nem tölti be a képet, csak a keretet.

Valaki tudna segíteni?

Arduino kód:

  1. #include <SPI.h>
  2. #include <Ethernet.h>
  3. #include <SD.h>
  4.  
  5. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  6. IPAddress ip (192,168,1,4); // IP address, may need to change depending on network
  7. EthernetServer server(80);  // create a server at port 80
  8.  
  9. File webFile;
  10.  
  11. void setup()
  12. {
  13.     Ethernet.begin(mac, ip);  // initialize Ethernet device
  14.     server.begin();           // start to listen for clients
  15.     Serial.begin(9600);       // for debugging
  16.    
  17.     Serial.println("SD kártya keresés...");
  18.     if (!SD.begin(4)) {
  19.         Serial.println("Hiba! Nem látom az SD kártyát!");
  20.         return;    // init failed
  21.     }
  22.     Serial.println("Siker! SD kártya beolvasva.");
  23.     if (!SD.exists("index.htm")) {
  24.         Serial.println("Hiba! Nem találom az index.htm fájlt!");
  25.         return;  // can't find index file
  26.     }
  27.     Serial.println("Siker! Index.htm beolvasva.");
  28. }
  29.  
  30. void loop()
  31. {
  32.     EthernetClient client = server.available();  // try to get client
  33.  
  34.     if (client) {  // got client?
  35.         boolean currentLineIsBlank = true;
  36.         while (client.connected()) {
  37.             if (client.available()) {   // client data available to read
  38.                 char c = client.read(); // read 1 byte (character) from client
  39.                 // last line of client request is blank and ends with \n
  40.                 // respond to client only after last line received
  41.                 if (c == '\n' && currentLineIsBlank) {
  42.                     // send a standard http response header
  43.                     client.println("HTTP/1.1 200 OK");
  44.                     client.println("Content-Type: text/html");
  45.                     client.println("Connection: close");
  46.                     client.println();
  47.                     // send web page
  48.                     webFile = SD.open("index.htm");        // open web page file
  49.                     if (webFile) {
  50.                         while(webFile.available()) {
  51.                             client.write(webFile.read()); // send web page to client
  52.                         }
  53.                         webFile.close();
  54.                     }
  55.                     break;
  56.                 }
  57.                 // every line of text received from the client ends with \r\n
  58.                 if (c == '\n') {
  59.                     // last character on line of received text
  60.                     // starting new line with next character read
  61.                     currentLineIsBlank = true;
  62.                 }
  63.                 else if (c != '\r') {
  64.                     // a text character was received from client
  65.                     currentLineIsBlank = false;
  66.                 }
  67.             } // end if (client.available())
  68.         } // end while (client.connected())
  69.         delay(1);      // give the web browser time to receive the data
  70.         client.stop(); // close the connection
  71.     } // end if (client)
  72. }


index.htm kód:

  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <title>Arduino Image </title>
  5.     </head>
  6.     <body>
  7.         <h1>Arduino SD Image <h1>
  8.         <img src="x.jpg" />
  9.     </body>
  10. </html>
A hozzászólás módosítva: Márc 14, 2015
(#) icserny válasza ISF79 hozzászólására (») Márc 14, 2015 /
 
Ha az index.htm-en kívül mást is letölthetővé akarsz tenni, akkor természetesen olvasni és értelmezni kell a beérkező kérelmeket. Ha például a kliens az x.jpg állományt kéri le, akkor ne az index.htm állományt küldd ki neki. Figyelem: az x.jp kiküldésekor a fejlécben értelemszerűen más kell, hogy legyen a Content-Type értéke is. Ha 1-2 hónapot visszanézel, ebben a topikban találsz erre vonatkozó hozzászólásokat.
(#) ISF79 válasza icserny hozzászólására (») Márc 14, 2015 /
 
Köszönöm.
(#) Kovidivi hozzászólása Márc 15, 2015 /
 
Sziasztok!
Watchdog timer-t használtatok már? Be van állítva 8mp-re, be is következik az időtúllépés, talán még egy resetet is kap, de nem indul el a főprogram. Lehetséges, hogy a bootloader nem engedi tovább a futást? Tápfeszültség ráadása után kb. 9.5mp-cel következik be a képszakadás. Ha csak sima interruptot állítok be, az pedig le sem fut. Arduino mini pro-ról van szó. Köszi.

  1. MCUSR=0;                 // Clear the WDT reset flag
  2.                 WDTCSR|=((1<<WDCE)|(1<<WDE));   // Enable the WD Change Bit
  3.                 WDTCSR=0x00;  
  4.                
  5.                 cli();
  6.                 WDTCSR|=((1<<WDCE)|(1<<WDE));   // Enable the WD Change Bit
  7.                 WDTCSR=(1<<WDE)|(1<<WDP3)|(1<<WDP0);   // Set Timeout to ~8 seconds
  8.                 sei();
  9.                 WDTCSR=(1<<WDIE)|(1<<WDE); // próbáltam wde nélkül is.
(#) ISF79 válasza icserny hozzászólására (») Márc 15, 2015 /
 
Sajnos iszonyat lassú. Kb. 100kb méretű képet szeretnék megjeleníteni, de 10-15mp mire betölti. (nincs módom, hogy átméretezzem)
Ez a modul (W5100) miatt ilyen lassú vagy az SD kártyáról a SPI miatt ilyen a sebesség?
Láttam W5200 jelölésű ethernet shieldet arduinohoz. Azzal van tapasztalata valakinek?
(#) GPeti1977 válasza ISF79 hozzászólására (») Márc 15, 2015 /
 
Próbáld meg hogy 512byte-ot olvasol a kártyáról elmented tömbbe majd ezt az 512-t kiírod clientprint-tel a fájl végéig.
(#) Kovidivi válasza Kovidivi hozzászólására (») Márc 15, 2015 /
 
Ezt találtam: "The more severe issue is, that the bootloader does not de-activate the watchdog upon reset, so that one can end up with endless resets. There are patched bootloaders available, but without official Arduino support this remains tricky." Nálam ha 8mp-re van állítva az időzítés, attól ha lefutna a bootloader, setupból már le tudnám nullázni. De nem is lép be még a setup-ba sem. Kipróbálom Atmega128-on bootloader nélkül, hátha a kód a hibás...
(#) mechanika hozzászólása Márc 15, 2015 /
 
Sziasztok!

char n[20];

A fenti sorral:
létrehoztunk egy változókat tartalmazó tömböt, amit n-nek nevezünk és megadtuk, hogy 20 eleme van.

Jól gondolom?
(#) kapu48 válasza mechanika hozzászólására (») Márc 15, 2015 /
 
Igen!
És a típusa 1 Byte -128 tol 127. terjedő szám.
(#) erdeidominik1999 hozzászólása Márc 15, 2015 /
 
Sziasztok! Hogyan tudnék lcd-n több mint 8 karaktert definiálni, mert ha definiálok egyet mondjuk a 0. helyre, kiiratom, aztán újradefiniálom a 0. helyet, akkor az előzőt is lecseréli.
(#) kapu48 válasza erdeidominik1999 hozzászólására (») Márc 15, 2015 /
 
Lecseréled az LCD-t GLCD-re!
Következő: »»   94 / 852
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem