Skocz do zawartości

r.ziomber

Społeczność Astropolis
  • Postów

    2 750
  • Dołączył

  • Ostatnia wizyta

Odpowiedzi opublikowane przez r.ziomber

  1. Najwieksza bolaczka grup FB jest prawie zerowe indeksowanie przez Google. Sama wyszukiwarka FB jest tez mocno kulawa (czasem nawet nie znajduje potrzebnych materialow archiwalnych).

    Zamieszczanie tam cenniejszych informacji jest nieodpowiednie, bo nie zapewnia dostepu do nich przez wyszukiwarke.

    No i jest juz multum grup poswieconych astronomii, po co tworzyc kolejne?

    • Lubię 1
  2. W dniu 8.08.2018 o 00:31, Sebo_b napisał:

     jeśli nie jest stale to DynDNSa. 

    Troche OT. Obsluga Dynamic DNS https://freedns.42.pl dla ESP8266 napisana w Arduino. Zastosowanie: ESP caly czas monitoruje obserwatorium i w razie potrzeby zdalnie uruchamia komputer czy Raspberry Pi. Przy okazji dba tez o uaktualnienie IP rekordu A naszej domeny.

    #include <ESP8266HTTPClient.h>
    #include <ESP8266WiFi.h>
    #include <WiFiClientSecure.h>
    struct FreeDNSsettings {
      String domain;
      String subdomain;
      String newaddress;
      String user;
      String password;
      String ttl;
    } dnsset;
    
    void setup() {
      dnsset.domain = "";
      dnsset.subdomain = "";
      dnsset.user = "";
      dnsset.password = "";
      dnsset.ttl = "120";
      Serial.begin(9600);                                  //Serial connection
      WiFi.begin("Ssid", "password");   //WiFi connection
    
      while (WiFi.status() != WL_CONNECTED) {  //Wait for the WiFI connection completion
        delay(500);
        Serial.println("Waiting for connection");
      }
    }
    
    void loop() {
      if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
        String myIP = publicIP();
        String hostIP = gethostbyname(dnsset.subdomain + "." + dnsset.domain);
    
        if (myIP != hostIP)
        {
          dnsset.newaddress = myIP;
          updateDynDNS();
          Serial.println(hostIP);
        }
      } else {
        Serial.println("Error in WiFi connection");
      }
      delay(15 * 60 * 1000);
    }
    
    String publicIP() {
      String myIP;
      HTTPClient http;
      http.begin("http://ip.42.pl/raw"); //Specify request destination
      int httpCode = http.GET();                                                                  //Send the request
    
      if (httpCode > 0) { //Check the returning code
        myIP = http.getString();   //Get the request response payload
      }
      return myIP;
    }
    
    String gethostbyname(String host)
    {
      IPAddress ipAddress;
      WiFi.hostByName(host.c_str(), ipAddress);
      return String(ipAddress[0]) + String(".") + \
             String(ipAddress[1]) + String(".") + \
             String(ipAddress[2]) + String(".") + \
             String(ipAddress[3]);
    }
    
    void updateDynDNS() {
      String xml = "<?xml version='1.0'?>\r\n"
                   "<methodCall>\r\n"
                   "<methodName>xname.updateArecord</methodName>\r\n"
                   "<params>\r\n"
                   "<param>\r\n"
                   "<value><struct>\r\n"
                   "<member>\r\n"
                   "<name>name</name>\r\n"
                   "<value><string>" + dnsset.subdomain + "</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>zone</name>\r\n"
                   "<value><string>" + dnsset.domain + "</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>newaddress</name>\r\n"
                   "<value><string>" + dnsset.newaddress + "</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>oldaddress</name>\r\n"
                   "<value><string>*</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>updatereverse</name>\r\n"
                   "<value><string>0</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>user</name>\r\n"
                   "<value><string>" + dnsset.user + "</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>ttl</name>\r\n"
                   "<value><string>" + dnsset.ttl + "</string></value>\r\n"
                   "</member>\r\n"
                   "<member>\r\n"
                   "<name>password</name>\r\n"
                   "<value><string>" + dnsset.password + "</string></value>\r\n"
                   "</member>\r\n"
                   "</struct></value>\r\n"
                   "</param>\r\n"
                   "</params>\r\n"
                   "</methodCall>";
    
      String http = "POST /xmlrpc.php HTTP/1.1\r\n"
                    "Host: freedns.42.pl\r\n"
                    "Accept-Encoding: gzip\r\n"
                    "Content-Type: text/xml\r\n"
                    "User-Agent: Python-xmlrpc/3.5\r\n"
                    "Content-Length: " + String(xml.length()) + "\r\n"
                    "\r\n";
    
      xml = http + xml;
    
      WiFiClientSecure client;
      IPAddress ipAddress;
      WiFi.hostByName("freedns.42.pl", ipAddress);
      client.connect(ipAddress, 443);
      client.print(xml);
    }

     

  3. W dniu 25.08.2018 o 10:47, Behlur_Olderys napisał:

    static_cast wygląda najbardziej elegancko, ale znowu - muszę sam się przekonać :)

    Przy okazji millis() mozna sobie samemu "przekrecic". Dla ATmega328P dodaj do setup()

      extern volatile unsigned long timer0_millis;
      noInterrupts();
      timer0_millis += 4294963295;
      interrupts();

    i bedziesz mial 4 s do przekroczenia zakresu unsigned long.

    Przy okazji przydatne, jesli chcemy korygowac millis() o czas uspienia kontrolera i nie bawic sie w podmiane millis() na actualMillis() we wszystkich plikach.

    unsigned long actualMillis()
    {
    	return millis() + sleepCorrection;
    }

     

  4. 2 godziny temu, Behlur_Olderys napisał:

    Z drugiej strony, jeśli aplikacja jest tak wyżyłowana performance'owo, że trzeba się martwić takimi rzeczami, to znak, że pora zastanowić się nad zmianą hardware'u :)

    STM32!

    https://github.com/stm32duino

    https://www.aliexpress.com/item/1pcs-STM32F103C8T6-ARM-STM32-Minimum-System-Development-Board-Module-raspberry-raspberri-pi-2-watch-nmd-diy/32786765274.html

     

    A ESP32 jest dwurdzeniowe i mozna jeden rdzen poswiecic na timer.

    https://groups.google.com/forum/#!topic/pl.misc.elektronika/K3eQYMWwdf4

  5. 2 godziny temu, Behlur_Olderys napisał:

    Ogólnie - gdyby zaimplementować z boku gdzieś najprostszą protezę std::vector to mój "idealny" kod wyglądałby tak: (pseudo kod raczej)

    Jest pare bibliotek. Przypuszczam jednak, ze beda miec istotny narzut, dlatego cuduje realloc z C. Przyznaje jednak, ze nie testowalem ich wplywu na wydajnosc.

    https://github.com/maniacbug/StandardCplusplus

    https://www.arduinolibraries.info/libraries/arduino-stl

    https://github.com/zacsketches/Arduino_Vector

  6. Czy moge prosic o weryfikacje? Zamiast

    W dniu 23.08.2018 o 13:16, Sebo_b napisał:

     

    
    // constructor
    nextCall = now() + interval;
    
    //active loop
    if ( nextCall < now() ) {
      nextCall += interval;
      callWhatever();
    }

    proponuje

    #include <limits.h>
    
    // constructor
    nextCall = now() + interval;
    
    //active loop
    if ( nextCall < now() && now() - nextCall < ULONG_MAX / 2 ) {
      nextCall += interval;
      callWhatever();
    }

    Powod: przedzial czasu obejmujacy przekroczenie zakresu zmiennej. now() bedzie wtedy olbrzymie a nextCall male. Warunek nextCall < now() zostanie wiec spelniony.

    Standardowe rozwiazanie https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay nie sprawia klopotow z overflow, ale kumuluje opoznienie kolejnych krokow.

    • Lubię 1
  7. Ale Arduino bez dodatkowych bibliotek nie obsluguje std::vector (w ogole STD) i stad takie mieszanie C++ z C.

    https://github.com/maniacbug/StandardCplusplus

    6 godzin temu, Behlur_Olderys napisał:

    Zasadniczo rozróżnianie tasków "zwykłych" i ET wydaje się również niepotrzebne - no, chyba że oszczędność pamięci.

    Zadanie "doczesne" przechowuje jedynie informacje o interwale. Wykonywane kilka razy dodatkowo musi miec informacje o ilosci cykli i "poczekalni" przed pierwszym wykonaniem.

     

    6 godzin temu, Behlur_Olderys napisał:

    Dlatego proszę,  nie traktuj tego jako krytykę, a raczej jako analizę porównawczą

    Ale ja oczekuje krytyki! Chce sie uczyc od zawodowych programistow i doskonalic swoje znikome umiejetnosci.

    Jesli tylko masz czas napisac, z checia wyslucham, co zrobilem zle!

     

    Mam jeszcze glupi pomysl, o ktory byc moze rozbuduje swoj timer. Terminarz oparty na... delay(). No dobra, nie na delay(), a na uspijMikrokontroler(), ale w zewnetrznym zachowaniu to prawie to samo :) Po prostu znajde najblizsze zadanie w tabelicach time i timeET i do tego czasu uspie mikrokontroler. Bedzie to dodatkowa opcja, bo oczywiscie nienadajaca sie do kazdego projektu.

    PS. Ktos kiedys powiedzial, ze na delay() nie da sie zrobic wielozadaniowosci. Dlatego tez chce ja zrobic :P

  8. Na poczatku swojej przygody z Arduino napisalem cos takiego. Przygotowane z mysla o interwalometrze dla lustrzanki. Zadania typu "wykonaj 10 zdjec z interwalem 2s, poczekaj 12s przed startem".

     

    Uzycie:
    - co 2000 ms wykonaj funkcje blinkLED

    timer.addEverytime(2000, blinkLED);


    - wykonaj dwa razy funkcje itWorks co 2000 ms, poczekaj 300ms przed pierwszym wykonaniem
    timer.addTask(300, 2, 2000, itWorks);

    class RZTimer
    {
      public:
        size_t tasks, tasksET;
        typedef void( * makeThisT )();
    
        typedef struct {
          unsigned long time;
          unsigned int interval, iterations, iterationsDone;
          makeThisT makeThis;
        } parameter;
        parameter *parameters;
    
        typedef struct {
          unsigned long timeET;
          unsigned int intervalET;
          makeThisT makeThisET;
        } parameterET;
        parameterET *parametersET;
    
        void run();
        size_t addTask(unsigned int, unsigned int, unsigned int, void (*makeT)());
        void removeTask(size_t);
        size_t addEverytime(unsigned int, void (*makeT)());
        void removeEverytime(size_t);
        size_t findTaskID(void (*makeT)());
        size_t findTaskIDEverytime(void (*makeT)());
    };
    
    size_t RZTimer::addTask(unsigned int _wait, unsigned int _iterations, unsigned int _interval, void (*makeT)())
    {
    	tasks++;
    	parameters = (parameter*) realloc(parameters, tasks * sizeof(parameter));
    	parameters[tasks - 1].time = millis() + _wait;
    	parameters[tasks - 1].interval = _interval;
    	parameters[tasks - 1].iterations = _iterations;
    	parameters[tasks - 1].iterationsDone = 0;
    	parameters[tasks - 1].makeThis = makeT;
    	
    	if (parameters[tasks - 1].iterations == 0)
    	{
    		parameters[tasks - 1].iterations = 1;
    	}
    	return tasks - 1;
    }
    
    size_t RZTimer::addEverytime(unsigned int _interval, void (*makeT)())
    {
    	tasksET++;
    	parametersET = (parameterET*) realloc(parametersET, tasksET * sizeof(parameterET));
    	parametersET[tasksET - 1].timeET = millis();
    	parametersET[tasksET - 1].intervalET = _interval;
    	parametersET[tasksET - 1].makeThisET = makeT;
    	
    	//makeT();
    	return tasksET - 1;
    }
    
    void RZTimer::run()
    {
    	for (size_t i = 0; i < tasks; i++) {
    		if (parameters[i].iterations)
    		{
    			if (static_cast<long>(millis() - parameters[i].time) >= 0)
    			{
    				parameters[i].time += parameters[i].interval;
    				parameters[i].makeThis();
    				parameters[i].iterationsDone = parameters[i].iterationsDone + 1;
    				if (parameters[i].iterationsDone >= parameters[i].iterations)
    				{
    					removeTask(i);
    				}
    			}
    		}
    	}
    	
    	for (size_t i = 0; i < tasksET; i++) {
    		if (static_cast<long>(millis() - parametersET[i].timeET) >= 0)
    		{
    			parametersET[i].timeET += parametersET[i].intervalET;
    			parametersET[i].makeThisET();
    		}
    	}
    }
    
    void RZTimer::removeTask(size_t _task)
    {
    	if (_task < tasks) {
    		for (size_t i = _task; i < tasks - 1; i++) {
    			parameters[i] = parameters[i + 1];
    		}
    		tasks--;
    		parameters = (parameter*) realloc(parameters, tasks * sizeof(parameter));
    	}
    }
    
    void RZTimer::removeEverytime(size_t _task)
    {
    	if (_task < tasksET) {
    		for (size_t i = _task; i < tasksET - 1; i++) {
    			parametersET[i] = parametersET[i + 1];
    		}
    		tasksET--;
    		parametersET = (parameterET*) realloc(parametersET, tasksET * sizeof(parameterET));
    	}
    }
    
    size_t RZTimer::findTaskID(void (*makeT)())
    {
    	for (size_t i = 0; i < tasks; i++) {
    		if (parameters[i].makeThis == makeT) {
    			return i;
    		}
    	}
    	return (size_t) ~0;   
    }
    
    size_t RZTimer::findTaskIDEverytime(void (*makeT)())
    {
    	for (size_t i = 0; i < tasksET; i++) {
    		if (parametersET[i].makeThisET == makeT) {
    			return i;
    		}
    	}
    	return (size_t) ~0;   
    }
    
    RZTimer timer;
    void blinkLED();
    
    void setup() {
      Serial.begin(9600);
      pinMode(LED_BUILTIN, OUTPUT);
      timer.addEverytime(2000, blinkLED);
      auto itWorks = []()->void {Serial.print("It Works! "); Serial.print(millis()); Serial.println(" ms");};
      timer.addTask(300, 2, 2000, itWorks);
    }
    
    void loop() {
      timer.run();
    }
    
    void blinkLED()
    {
      Serial.print("ON ");
      Serial.print(millis());
      Serial.println(" ms");
      digitalWrite(LED_BUILTIN, HIGH);
      auto blinkLEDoff = []()->void {digitalWrite(LED_BUILTIN, LOW); Serial.print("OFF "); Serial.print(millis()); Serial.println(" ms");};
      timer.addTask(1000, 1, 0, blinkLEDoff);
    }

     

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę.