Keresés

Hirdetés

Új hozzászólás Aktív témák

  • Janos250

    őstag

    Apropó! Ha már itt tartunk, hogy az ESP32 arduinoja ismeri a szabvány C++ zömét, akkor már mutatok a 11-nek más tulajdonságára is példát.
    Nem feltétlenül kell a több task esetén a freeRTOS task kezelését használni, lehet az oskolában C++ órán tanultakat is:

    #include <iostream>
    #include <thread>
    //#include <mutex>

    using namespace std;

    void helloWorld1() {
    for (uint8_t i = 0 ; i < 10 ; i++){
    cout << " Hello World1 ! " << endl;
    delay(1000) ;
    } ;
    } ;
    void helloWorld2() {
    for (uint8_t i = 0 ; i < 10 ; i++){
    cout << " Hello World2 ! " << endl;
    delay(2000) ;
    } ;
    } ;

    void setup() {
    Serial.begin(115200) ;
    delay(2000);

    thread szal1(helloWorld1);
    thread szal2(helloWorld2);

    szal1.join();
    szal2.join();
    }

    void loop() {
    }

    Egyre több minden szól az ESP32 mellett :)

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz tvamos #8772 üzenetére

    "Nem pont értem, hogy mi a különbség ez, meg a thread/join megoldás között"

    Gyakorlatilag semmi. Mindkettő ugyanazt csinálja, csak az egyik a szabványos C++-ban, a másik meg a freeRTOS-ben van megfogalmazva. Az xTaskCreatePinnedToCore esetén azt is megadhatod, hogy melyik magon fusson. A freeRTOS verzióban prioritást is adhatsz, ami bizonyos esetekben előny lehet. Viszont a thread/join használata egyszerűbb, de kevésbé rugalmas.

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz tvamos #10061 üzenetére

    Esetleg a szabványos thread használat?
    http://arduinouser.hu/esp32/AszalakEsAzESP32.pdf[link]
    Definiálunk néhány szálat (thread) pl. így: thread szal1.(hellowrld1), ahol a helloworld1 egy függvény
    Aztán amikor úri kedvünk úgy tartja, elindítjuk, akárhányat egymás mellett.
    pl. szail1.join()

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz _q #10286 üzenetére

    Nem próbáltad thread -del?
    Akkor az op. rendszer állítgatja be a prioritásokat.
    http://arduinouser.hu/esp32/AszalakEsAzESP32.pdf

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz DigitXT #11889 üzenetére

    "az Arduino-féle String implementáció egy nagy sz"
    "nem igazán ajánlott használni."
    Így igaz. A nagybetűs String valóban gyengécske, de azt is mondjuk meg, hogy mit érdemes használni:
    a kisbetűs string viszont jó.
    Ismét mondom, hogy nem ötegapám UNO, NANO, MEGA lapja az, amit érdemes használni, hanem valami korszerűbb,
    ami - mondhatni - nem drágább, de sokkal többet tud, és az UNO-ra, stb.-re írt programok símán áttehetők rá,
    ha nincs benne valami nagyon hardware közeli dolog.
    Mint már többször mondtam, én mostanság az ESP32-t használom.
    5 dollárért megvehető postával együtt.
    https://www.banggood.com/Geekcreit-30-Pin-ESP32-Development-Board-WiFibluetooth-Ultra-Low-Power-Consumption-Dual-Cores-ESP-32-ESP-32S-Board-p-1461896.html?rmmds=search&cur_warehouse=CN
    Vagy az UNO mintájára:
    https://www.banggood.com/LILYGO-TTGO-ESP32-WiFi-bluetooth-Board-4MB-Flash-UNO-D1-R32-Development-Board-p-1163967.html?rmmds=search&cur_warehouse=CN
    Megnéztem a régi Arduino String osztályát. Bizony elég sok tagfüggvény nincs benne, ami a C++ -ban benne van. Példának az appendet vettem,
    hogy a részletesebb infók netről megtekinthetők legyenek.
    Ha már itt tartottam, még pár - szintén netről szedett - példát is beleraktam.
    A mostani C++11 számos olyan dolgot is tartalmaz, amit az ősrégiek nem.
    Használhatjuk az alábbiakat:
    #include <array>
    #include <atomic>
    #include <chrono>
    #include <condition_variable>
    #include <forward_list>
    #include <future>
    #include <initializer_list>
    #include <mutex>
    #include <random>
    #include <ratio>
    #include <regex>
    #include <scoped_allocator>
    #include <system_error>
    #include <thread>
    #include <tuple>
    #include <typeindex>
    #include <type_traits>
    #include <unordered_map>
    #include <unordered_set>
    Ezek közül is raktam be példákat. Hogy miért jobb pl. az array, a chrono, a threadhasználata? Mert ez szabványos, bárhol ugyanígy fut, nem olyasmit tanulunk meg, amit máshol nem tudunk használni.
    Íme:
    Eredetileg ez egyetlen program lenne, de PH szerkesztője valamiért darabokra szedte.
    #define __cplusplus  201103L
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <array>
    #include <iterator>
    #include <chrono>
    #include <ctime>
    #include <thread>
    //ESP32 Dev Module
    void setup() {
     
    //http://www.cplusplus.com/reference/string/string/append/
      std::string str;
      std::string str2="Writing ";
      std::string str3="print 10 and then 5 more";
      // used in the same order as described above:
      str.append(str2);                       // "Writing "
      str.append(str3,6,3);                   // "10 "
      str.append("dots are cool",5);          // "dots "
      str.append("here: ");                   // "here: "
      str.append(10u,'.');                    // ".........."
      str.append(str3.begin()+8,str3.end());  // " and then 5 more"
    //  str.append<int>(5,0x2E);                // "....."
      std::cout << str << '\n';

    /*
    //A String (nagy S) a regi Arduino string kezelese
    // ebben nincs append, forditasi hibat jelez
      String xstr;
      String xstr2="Writing ";
      String xstr3="print 10 and then 5 more";
      // used in the same order as described above:
      xstr.append(xstr2);                       // "Writing "
      xstr.append(xstr3,6,3);                   // "10 "
      xstr.append("dots are cool",5);          // "dots "
      xstr.append("here: ");                   // "here: "
      xstr.append(10u,'.');                    // ".........."
      xstr.append(xstr3.begin()+8,xstr3.end());  // " and then 5 more"
    */

    //Ez is egy netrol vett pelda
    //https://stackoverflow.com/questions/2066184/how-to-use-c-string-streams-to-append-int
        std::stringstream stream("Something ");
        stream.seekp(0, std::ios::end);
        stream << 12345;
        std::cout << stream.str();
        

    // C++11 array
    //https://en.cppreference.com/w/cpp/container/array
        // construction uses aggregate initialization
        std::array<int, 3> a1{ {1, 2, 3} }; // double-braces required in C++11 prior to the CWG 1270 revision
                                            // (not needed in C++11 after the revision and in C++14 and beyond)
        std::array<int, 3> a2 = {1, 2, 3};  // never required after =
        std::array<std::string, 2> a3 = { std::string("a"), "b" };
     
        // container operations are supported
        std::sort(a1.begin(), a1.end());
        std::reverse_copy(a2.begin(), a2.end(), 
                          std::ostream_iterator<int>(std::cout, " "));
     
        std::cout << '\n';
     
        // ranged for loop is supported
        for(const auto& s: a3)
            std::cout << s << ' ';

    // C++11 chrono
    //https://en.cppreference.com/w/cpp/chrono
         auto start = std::chrono::system_clock::now();
        std::cout << "f(42) = " << fibonacci(42) << '\n';
        auto end = std::chrono::system_clock::now();
     
        std::chrono::duration<double> elapsed_seconds = end-start;
        std::time_t end_time = std::chrono::system_clock::to_time_t(end);
     
        std::cout << "finished computation at " << std::ctime(&end_time)
                  << "elapsed time: " << elapsed_seconds.count() << "s\n";

    // C++11  thread
    //https://en.cppreference.com/w/cpp/thread
    //https://thispointer.com/c-11-multithreading-part-1-three-different-ways-to-create-threads/
        std::thread threadObj1(thread_function);
        std::thread threadObj2(thread_function);
     
        if(threadObj1.get_id() != threadObj2.get_id())
            std::cout<<"Both Threads have different IDs"<<std::endl;
     
            std::cout<<"From Main Thread :: ID of Thread 1 = "<<threadObj1.get_id()<<std::endl;    
        std::cout<<"From Main Thread :: ID of Thread 2 = "<<threadObj2.get_id()<<std::endl;    
     
        threadObj1.join();    
        threadObj2.join(); 

    }
    void loop() {
    }
    // mert a chrono minta hasznalja
    long fibonacci(unsigned n)
    {
        if (n < 2) return n;
        return fibonacci(n-1) + fibonacci(n-2);
    }
    //// mert a thread minta hasznalja
    void thread_function()
    {
        std::cout<<"Inside Thread :: ID  = "<<std::this_thread::get_id()<<std::endl;    
    }

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz Djstefan1848 #12634 üzenetére

    Nem másra ráerőltetni akarom a véleményem, csak egy kis figyelem felhívás céljából elmondom:
    Djstefan1848 kérdezi, de KFORboy problémájára is ez a legegyszerűbb megoldás:
    Hogyan lehet arduinot programozni úgy, hogy 2, vagy több párhuzamos loop folyamatot futtasson egymástól függetlenül ?
    Annak ellenére, hogy azt írod, hogy újonc vagy, nagyon jól látod a problémát. Több loop kellene párhuzamosan. Ez a párhuzamos szálak futtatása egymás mellett. Hogy van-e ez arduinoban? Erre még így nem lehet válaszolni, mert az arduino programozás is annyiféle, ahányféle a kontroller. A régi Atmel kontrollerekkel valószínűleg nehezebben oldható meg, de itt nem ér véget az arduino világ.
    Kezdjük egyből az egyik felső szeletén:
    Az ESP32 arduinojában van több lehetőség is, hogy hogyan lehet arduinot programozni úgy hogy 2, vagy több párhuzamos
    "loop" folyamatot futtasson egymástól függetlenül.
    Az egyik lehetőség a C++ párhuzamos szálai (thread). Ha nem várakoztatod őket egymásra, akkor nyugisan elvannak egymás mellett.
    Vagy a freeRTOS taskjait használod. Ez rugalmasabb. Ezekben a delay nem igazi delay, hanem átadja a vezérlést más várakozó tasknak.
    Az ESP8266-on is van valami, ami ennek a kisöccse, de már nem pontosan emlékszem, egy ideje már nem használom. Egymás mellett több PWM jellegű vezérlést kellett futtatnom, különböző, és folyamatosan változó, de elég hosszú, több szekundumos periódusidőkkel, de demo módon. Van egy lib, ami azt csinálja, hogy egy beállított idő elteltével megcsinál valamit. Előkotortam egy régi programot, ezt használja:
    https://github.com/esp8266/Arduino/tree/master/libraries/Ticker
    Azonkívül van ez a lehetőség is schedulerre:
    https://github.com/anmaped/esp8266-scheduler
    Ezt nem próbáltam. Ez elvileg Atmel procikon is biztosít
    párhuzamos futtatást, nem tudom, van-e valaki, aki használta már. Persze a Ticker is az arduino schedulerét használja.
    Lehet persze azt csinálni, hogy járogatunk körbe-körbe, és mindig megnézzük, hogy kell-e valakinek valamit csinálni.
    Mint már többször írtam, én szinte csak ESP32-t használok. Egy UNO ezer Ft, egy ESP32 kétezer. Ennyit igazán megér a kényelem, hiszen ami
    UNO-n megy, az ESP32-n is, de fordítva nem, tehát egyáltalán nincs szükségem UNO-ra.

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz And #12931 üzenetére

    Egy régi project dobozomban találtam egy Mega 2560-at. Gyorsan ki is próbáltam. A mintapélda fut rajta, bár az xTaskCreate második paraméterében - az egyébként tök fölösleges - idézőjeles név elől az átdefiniálást törölni kellett.
    Ezen felbuzdulva próbáltam rákeresni, hogy C++11 ügyben mi újság. Azt írják, hogy támogatja, de ez a támogatás meglehetősen gyér. Pl. egyből elakadt a fordítás a thread-en és a cout-on is. Pedig a cout nem egy ritka jószág.
    Az ESP32-n nincs gond, az arduino IDE alatt fordítva, ezek (is) simán mennek.

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz Tankblock #16614 üzenetére

    Igazad van, az RTOS nem operációs rendszer olyan értelemben, hogy nem tudok konzolról ilyen-olyan userként bejelentkezni, programokat futtatni, de nekem erre egy mikrokontrolleren nincs is szükségem. Amire szükségem van, azt tudja. Legalábbis az Espressif kiegészítéseivel. Tudja a fájlok kezelését úgy, hogy ha írok neki egy fájlnak a C szerinti megnyitását, tudja mi az, vagy ha azt mondom neki, hogy cout, tudja miről beszélek.
    Ha valamelyik perifériát fájlként akarom használni, akkor persze meg kell hozzá írnom a drivert, de ezt be tudom illeszteni az ő rendszerébe, beírja a fájl leíró táblába, és onnantól már fájlként (is) tudom használni. Kell persze saját magamnak írni drivert, de már a DOS-hoz is saját magunk írtunk COM port kezelő drivert, mert az eredeti nem megszakítással dolgozott, pedig az Ix86x proci tudta.
    Vagy, ha nem akarom az ő thread kezelését használni, hanem a programban szerepel a thread és a join, tudja, mit akarok, a fordító le tudja fordítani az ő API-jaira.
    Végezetül, ami elvárásom nekem van egy mikrokontroller nem tudom, minek nevezzemjétől, az ebben az ESP32-ben benne van. Mellesleg viszonylag korszerű fordítót használ, bár nagyon sok mindent nem használok ki, mert például lambdát csak minden második szökőévben, bár azzal számos dolog tömörebb. :)

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz tonermagus #16629 üzenetére

    "Egyszerűen csak profibbnak érezné ha ESP/STM-en futna..."
    Nem az a lényeg a váltásnál, hogy "profibb"!
    A korszerűbb technikára való áttérésnek az az elsődleges előnye, hogy megtanulod.
    Évek múltával úgyis mindenből a korszerűbb jön elő. Én használtam a Z80-at. Ami akkor kellett, meg tudtam vele oldani, mert nem is gondoltam olyan dolgokra, ami azzal ne lett volna megoldható. Ma már nagyon nem szívesen dolgoznék Z80-al, pedig még valószínűleg kerülne 1-2 darab belőle, és vannak olyan dolgok, amit azzal is meg tudnék oldani.
    A jelen problémára visszatérve: Az, hogy egy csomó minden hardverben meg van oldva, ha azokat az emberfia megismeri, azok azért hasznosak.
    Továbbá a multitasking szisztéma is olyan, hogy nagyon sok mindent világosabban, áttekinthetőbben lehet vele megoldani. Mondok egy példát a saját dolgomból.
    Hőmérő méri a hőmérsékletet (akár Z80-al is meg tudnám oldani, de nem teszem), és időnként WiFi-n átküldi egy másik lapra, ami mindenféléket csinál. Hogyan oldjuk ezt meg? Időnként lekérdezzük a ciklusban, hogy jött-e új adat, ha igen, akkor azt beolvassuk, és beírjuk, hogy onnantól kezdve azzal számoljunk.
    ESP32-n: egyik task semmi mást nem csinál, csak megnézi, érkezett-e új adat, ha igen, akkor azt beteszi a globális változóba, így mindig automatikusan a legfrissebb adattal történik a további meló. Az "időnként megnézi" azt jelenti, hogy semmi más nincs egyik taskban, mint "megnézi", ha van beolvassa, majd delay. Ugyanis a multitasking esetén a delay nem jelenti azt, hogy ténylegesen várakozik, hanem, hogy a várakozás alatt egyszerűen nem megy rá a vezérlés arra a taskra, hanem fut a többi. Az már csak hab a tortán, hogy két mag van, és megválogathatjuk, ha akarjuk, hogy melyik task melyik magon fusson. Így ídőkritikus dolgokat lehet tenni önállóan az 1-es magra, ami meg ráér, az mehet minden a 0-ra. Ha meg nem akarjuk, akkor rábízhatjuk az oprendszerre, hogy válogasson, azaz egyszerűen használjuk a C++ thread-jét
    Például:
    thread szal1(helloWorld1);
    thread szal2(helloWorld2);

    Ha kell:
    szal1.join();
    szal2.join();

    Ő majd eldönti, mit hova tegyen.
    Ha ezeket megtanulod, akkor jössz rá, mire is használd. Evés közben jön meg az étvágy.

    "- 8 db PWM értéket mérek digitális bemeneten
    - 10 db PWM értéket írok ki digitális kimeneteken"

    Nem tudom, mennyire jól van a PWM a Megán megoldva, de STM-en, ESP32-n például igen kényelmesen, hardverből.

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz dzz #17345 üzenetére

    Erre mindenki mást javasol.
    Az én véleményem:
    Elsődlegesen a WiFi használata. Szerverre van többféle verzió a neten, mind kicsit más.
    Én nem azokat használom, hanem az alapot, tömören a lényege:
    WiFiServer server(80);
    WiFiClient client ;

    A loopban pedig a lényeg:
    client = server.available();

    if (client.available()) { // if there's bytes to read from the client,
    char c = client.read();

    Természetesen még jönnek hozzá a sallangok, például, hogy vége akkor van, ha két cr/lf jön egymásután.

    client.println(protocolHeader);
    client.println(httpHeader);
    client.print(body01);

    A végén:
    client.stop();

    Ezt így alapszinten használom. Ha valamelyik kész httpserver kezelőt használod, az egyszerűbb, de nekem ez kényelmes, és rugalmas.
    Olyasmi, mint a PHP, hogy írod azt, amit a WEB lapodra akarsz tenni.

    Aztán ott van az OS, a freeRTOS, amire sokan mondják, hogy igazából nem is OS, mert pl. nincsenek benne userek.
    Ezzel az esetek zömében nem kell foglalkozni, nem kell, hogy a user lássa.
    Ha párhuzamosan akarsz taskokat futtatni, akkor vagy a szabványos C++ módon teszed, és az OS eldönti, melyik magra teszi:

    thread szal1(helloWorld1);
    thread szal2(helloWorld2);
    szal1.join();
    szal2.join();

    A join akkor kell, ha be kell várni az adott szál befejezését,

    vagy kreálsz neki külön taskot, például:

    xTaskCreate(
    readTempr,
    "homersekletOlvas",
    5000,
    NULL,
    6,
    &homeroTaskHandle
    );

    Én ezzel például olvasom a hőmérsékleteket mindentől függetlenül a "readTempr" függvénnyel, és belerakom globális változókba, ezért nincs szükség paraméterekre, azaz NULL nullpointer. Itt szokott egy kis gubanc lenni annak, aki először használja, mert ide a paraméterekre (pl töm, struktúra) mutató pointert írunk, de az xTaskCreate void típusú pointert kér, ezért kényszerítéssel voidosítani kell, majd a függvényben ismét kényszeríteni az adott típusra. Ha el akarod dönteni, hogy melyik magra tedd, akkor azt is megadhatod. Én például szeretem az ilyen mellékes dolgokat a 0-ás magra tenni, mert ott fut magas prioritással a WiFi kezelés, az üresjáratokban pedig az én "mellékes" függvényeim, egymástól függetlenül. Például amit az előbb írtam, abban végtelen ciklus van. Beolvassa a hőmérsékleteket, beleteszi globális változóba, vár egy időt, majd újra olvas. Ilyen esetben a wait az nem tényleges várakozás, hanem a többi tasknak adja át a vezérlést. Mivel a hőmérsékletek byte-ban vannak, nem kell semmiféle zárás, hogy ne akkor olvasson az egyik, amikor már az adatok felét átírta a másik, és akkor hülyeséget kapjon, de ha több byte-os az adat, akkor kizárás szükséges..

    Aztán célszerű a rengeteg hardver perifériát kipróbálni.

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz Blasius #19703 üzenetére

    Az is lehet, ha bármi miatt (pl.) interrup, thread több szálú a program futása, akkor mutex ( lock() unlock() ) kéne használni. Nekem az utolsó sor is gyanús, hogy mi van akkor, ha előtte/közben/utána hajtódik végre valami kódrészlet, akár interrupttal.

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

  • Janos250

    őstag

    válasz hcl #22514 üzenetére

    Én még csak tervezem.
    Odáig már eljutottam, hogy a sima WiFiserverrel (vagy ha jobban tetszene sima C fájlkezeléssel) tudjam a websocketot használni, ne kelljen hozzá a spéci szerver, mert én nem nagyon szeretem a valaki által megírt, és néha alig, néha rosszul dokumentált könyvtárakat.
    Odáig már eljutottam, hogy a
    - WEB lap létrehozza a socketot,
    - megnyitja
    - Gombbal elküld valamit a szervernek,
    - Ha a szerverről érkezik valami azt feldolgozza (jelenleg kiírja)
    - A lezáráskor lezárja.

    Külön szálon fut, hogy semmit ne zavarjon, ne is látszódjék különösebben:
    thread thread_loop(loop);
      thread_loop.join(); // wait thread_loop end

    Az ESP32 programja megnézi a kliens (Firefox) által küldött kérés első várakozó karakterét beolvasás nélkül:
    (client.peek())
    , majd ez alapján eldönti (case), hogy mit kell csinálni,
    és azt megcsinálja, azaz
    - bejelentkezett a Firefox, hogy kéri a WEB lapot, akkor azt kell elküldeni,
    - vagy WEBsocket módon kíván csatlakozást, ha már a html csatlakozás megtörtént,
    - Vagy jön egy adatcsomag a Firefoxról,
    - vagy éppen én akarok valamit küldeni.(ez persze nem a FF-ról jön :-) )

    Ezeket csak azért írtam le, hogy ha valakinek szintén olyan mániája támadna, mint nekem, akkor nagyjából sejtse, miket kell megcsinálni.
    Jelenleg működik, de még az értelmes alkalmazásra (hőmérséklet figyelés, fűtés állítása csuszkával) még nincs átültetve.

    [ Szerkesztve ]

    Az amerikaiak $ milliókért fejlesztettek golyóstollat űrbéli használatra. Az oroszok ceruzát használnak. Én meg arduinot.

Új hozzászólás Aktív témák