Czujnik wiatru i deszczu

User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Przerobienia softu od shimano się nie podejmuję, a już tym bardziej gg. Jeśli masz jakieś doświadczenia w programowaniu to ten mój szkic jest na tyle prosto napisany, że bez problemu sobie poradzisz…
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Bernix
Posts: 93
Joined: Tue Jan 03, 2023 10:29 am

Post

Bernix wrote: Fri Nov 22, 2024 9:25 am
SOYER wrote: Fri Nov 22, 2024 8:10 am Jutro postaram się zrobić. Dzisiaj nie dam rady. Co konkretnie ma być w tym szkicu?
Dziękuję bardzo za zainteresowanie
W twoim projekcie jest:
ds
dht22
kpop wiatr chwilowy
kpop wiatr średni z ostatniej minuty
kpop deszcz
To już jest fantastyczny zestaw czujników, a czy możesz ustalić taki:
Dht22
Czujnik wilgotności gleby (pomiar analogowy) https://a.aliexpress.com/_EzNUsvP
Kpop deszczomierz https://a.aliexpress.com/_Eu3Ku5J
Czujnik natężenia światła BH1750
Czujnik deszczu (ten bez przekaźnika) https://a.aliexpress.com/_EJZyptF
Wiem że to już dużo ale jakby dało do tego dołożyć kpop wiatr chwilowy to byłby komplet.
Jeżeli uznasz że za dużo to w twoim projekcie jakby można było zamienić ds na ten czujnik wilgotności gleby.
Pozdrawiam


Coś chyba przekombinowałem. Czujnik wilgotności gleby i czujnik deszczu to chyba pomiary analogowe. Jeżeli tak to zostaje czujnik wilgotności gleby.
Trochę się pogubiłem z wpisami w wątku. To będziesz mógł zrobić szkic z takimi opcjami?
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

To ja się pogubiłem, napisz dokładnie co ma szkic robić, ale jeśli mam pisać cały szkic do obsługi SDS i tych wszystkich czujników to niestety nie mam na to czasu. Nigdy nie miałem np. SDS u siebie więc nie wiem która biblioteka działa. Za dużo niewiadomych. Jeśli chcesz coś z moich rozwiązań dołożyć do swojego kodu i nie wiesz jak, to wklej swój szkic i powiedz w czym pomóc.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Bernix
Posts: 93
Joined: Tue Jan 03, 2023 10:29 am

Post

Generalnie twój szkic jest super. Mnie chodzi o zamianę ds18b20 na czujnik natężenia światła oraz zaimplementowanie czujnika wilgotności gleby.
Z programowania to cienki jestem, raczej "konsumentem".
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

SOYER wrote: Sun Nov 10, 2024 5:19 pm Cześć, z racji tego, że jeden z użytkowników prosił mnie o dodanie dodatkowo obsługi czujnika SDS011, to poniżej wklejam szkic który to powinien robić. Jednak fizycznie nie mam tego czujnika, więc nie mam możliwości sprawdzenia czy ta biblioteka zastosowana i cały szkic będą współdziałać z czujnikiem.
Nie zapomnijcie dodać biblioteki:
https://github.com/ricki-z/SDS011
uzupełnić dane wifi, GUID i AUTH, oraz dane do logowania do serwera.

Jak ktoś ma taki czujnik to może sprawdzić czy to działa. Generalnie szkic bez problemu wgrał się na nodeMCU(8266), uruchomił, zalogował do serwera itd.

Szkic:

Code: Select all

#include <SuplaDevice.h>
#include <SDS011.h>  //  https://github.com/ricki-z/SDS011
#include <Timers.h>   //   https://github.com/nettigo/Timers
#include <supla/sensor/DHT.h>
#include <supla/sensor/DS18B20.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
  Supla::ESPWifi wifi("xx", "xx");
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4

#define rxPin 13 //D7 SDS011
#define txPin 15  //D8 SDS011
float p10, p25;
int error;
bool startOdczyt = 0;
bool odczyt = 0;
SDS011 my_sds;

Timer minut5;
Timer sekund30;
Timer minuta;
Timer sekund1;
Timer sekund6;

int rai=0;
bool r=0;
float mmM2=0;

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *rain = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P2 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P10 = nullptr;

void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai++;
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8;
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      average_kmh = temp_kmh / 10; 
      temp_kmh = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}

void sds(){
  if((minut5.available()) && (startOdczyt ==0)){
    sekund30.restart();
    startOdczyt = 1;
    odczyt = 1;
    my_sds.wakeup();
  }
  if((sekund30.available()) && (odczyt == 1)){
      error = my_sds.read(&p25, &p10);
       if (!error) {
        P2->setValue(p25);
        P10->setValue(p10);
        Serial.println("P2.5: " + String(p25));
        Serial.println("P10:  " + String(p10));
        minut5.restart();
        startOdczyt = 0;
        odczyt = 0;
        my_sds.sleep();
       }
  }
}

void setup() {
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
    
      my_sds.begin(rxPin, txPin); //RX, TX
  Serial.begin(9600);
  new Supla::Sensor::DS18B20(dsPin);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain = new Supla::Sensor::GeneralPurposeMeasurement();   
    P2 = new Supla::Sensor::GeneralPurposeMeasurement();
    P10 = new Supla::Sensor::GeneralPurposeMeasurement();
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minut5.begin(299999);
    sekund30.begin(30001);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    last_event = millis();
    last_event1 = millis();
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "svrxx.supla.org",  // SUPLA server address
                    "[email protected]",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendSupla();
    sds();
}
void sendSupla(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){  
      mmM2=rai*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      rain->setValue(mmM2);
      average_wind->setValue(average_kmh);
      rai=0;
      minuta.restart();
    }
}
@Bernix sprawdzałeś czy ten szkic działa z Twoim czujnikiem SDS?
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

@Bernix

Code: Select all

#include <SuplaDevice.h>
#include <SDS011.h>  //  https://github.com/ricki-z/SDS011
#include <Timers.h>   //   https://github.com/nettigo/Timers
#include <supla/sensor/DHT.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
  Supla::ESPWifi wifi("xx", "xx");
  
#define dsPin 14 //D5
#define dhtPin 5 //D1
#define windPin 12 //D6
#define rainPin 2  //D4
#define gleba_pin A0
#define rxPin 13 //D7 SDS011
#define txPin 15  //D8 SDS011
float p10, p25;
int error;
bool startOdczyt = 0;
bool odczyt = 0;
SDS011 my_sds;

Timer minut5;
Timer sekund30;
Timer minuta;
Timer sekund1;
Timer sekund6;

int rai=0;
bool r=0;
float mmM2=0;

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;


Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *rain = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P2 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P10 = nullptr;

const int analogInPin = gleba_pin;
class AnalogValue : public Supla::Sensor::GeneralPurposeMeasurement {
  public:
    AnalogValue(int pin) : pin(pin) {
    }

    void onInit() {
      pinMode(pin, INPUT);
      channel.setNewValue(getValue());
    }
    double getValue() {
      return analogRead(pin);
    }
  protected:
    int pin;
};
void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai++;
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8;
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      average_kmh = temp_kmh / 10; 
      temp_kmh = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}

void sds(){
  if((minut5.available()) && (startOdczyt ==0)){
    sekund30.restart();
    startOdczyt = 1;
    odczyt = 1;
    my_sds.wakeup();
  }
  if((sekund30.available()) && (odczyt == 1)){
      error = my_sds.read(&p25, &p10);
       if (!error) {
        P2->setValue(p25);
        P10->setValue(p10);
        Serial.println("P2.5: " + String(p25));
        Serial.println("P10:  " + String(p10));
        minut5.restart();
        startOdczyt = 0;
        odczyt = 0;
        my_sds.sleep();
       }
  }
}

void setup() {
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
    
      my_sds.begin(rxPin, txPin); //RX, TX
  Serial.begin(9600);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain = new Supla::Sensor::GeneralPurposeMeasurement();   
    P2 = new Supla::Sensor::GeneralPurposeMeasurement();
    P10 = new Supla::Sensor::GeneralPurposeMeasurement();
    new AnalogValue(analogInPin);
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minut5.begin(299999);
    sekund30.begin(30001);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    last_event = millis();
    last_event1 = millis();
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "svrxx.supla.org",  // SUPLA server address
                    "[email protected]",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendSupla();
    sds();
}
void sendSupla(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){  
      mmM2=rai*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      rain->setValue(mmM2);
      average_wind->setValue(average_kmh);
      rai=0;
      minuta.restart();
    }
}
Jest dodana obsługa odczytu analogowego(czujnik wilgotności gleby) na pinie A0, jako KPOP. Tylko nie wiem czy to będzie działać. Musisz sprawdzić, a przy okazji też czujnik SDS.
Last edited by SOYER on Mon Nov 25, 2024 8:44 pm, edited 1 time in total.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

@Bernix
tu masz dodatkowo z czujnikiem światła BH:

Code: Select all

#include <SuplaDevice.h>
#include <SDS011.h>  //  https://github.com/ricki-z/SDS011
#include <Timers.h>   //   https://github.com/nettigo/Timers
#include <supla/sensor/DHT.h>
#include <supla/network/esp_wifi.h>
#include <supla/sensor/general_purpose_measurement.h>
#include <BH1750.h>//https://github.com/claws/BH1750.git
#include <Wire.h>
  Supla::ESPWifi wifi("xx", "xx");
  
#define SDA_BH 19
#define SCL_BH 20
#define dhtPin 14 //D1
#define windPin 12 //D6
#define rainPin 2  //D4
#define gleba_pin A0
#define rxPin 13 //D7 SDS011
#define txPin 15  //D8 SDS011
float p10, p25;
int error;
bool startOdczyt = 0;
bool odczyt = 0;
SDS011 my_sds;

Timer minut5;
Timer sekund30;
Timer minuta;
Timer sekund1;
Timer sekund6;

int rai=0;
bool r=0;
float mmM2=0;

volatile int half_revolutions_time = 2; //Utworzenie zmiennej połowa pełnego obrotu (half revolutions)
volatile int rpm = 0;
unsigned long static  last_event = 0;
unsigned long static last_event1 = 0;
int sample = 0;
float moment_kmh;
float temp_kmh;
float correct_moment_kmh;
float average_kmh;

BH1750 lightMeter;

Supla::Sensor::GeneralPurposeMeasurement *moment_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *average_wind = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *rain = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P2 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *P10 = nullptr;
Supla::Sensor::GeneralPurposeMeasurement *lightSensor = nullptr;

const int analogInPin = gleba_pin;
class AnalogValue : public Supla::Sensor::GeneralPurposeMeasurement {
  public:
    AnalogValue(int pin) : pin(pin) {
    }

    void onInit() {
      pinMode(pin, INPUT);
      channel.setNewValue(getValue());
    }
    double getValue() {
      return analogRead(pin);
    }
  protected:
    int pin;
};
void ICACHE_RAM_ATTR rn(){// wektor przerwania deszczomierza
  unsigned long static last_event1 = 0;
  if (millis() - last_event1 < 50) {   //debouncing
    return;
  }
  rai++;
  last_event1 = millis();
}
 void ICACHE_RAM_ATTR rpm_fan() { //funkcja rpm_fan
  if (millis() - last_event < 5) {   //debouncing
    return;
  }
  half_revolutions_time = (millis() - last_event);
  last_event = millis();
}
void temporaryRPM(){
    noInterrupts(); 
    if((last_event + 2000) < millis()){    
     rpm=0;
     moment_kmh = 0;
     correct_moment_kmh = 0;
    }
    else{ 
      rpm = (30000 / half_revolutions_time) ;
      moment_kmh = 6.28 * 0.075 * rpm/60.0 * 3.6;// pi x promień czujnika x rpm/60s x ms->km/h
      if(moment_kmh < 10){
        correct_moment_kmh = moment_kmh * 2.8;
      }
      else if((moment_kmh >= 10) && (moment_kmh < 25)){
        correct_moment_kmh = moment_kmh * 2.7;
      }
      else if(moment_kmh >= 25){
        correct_moment_kmh = moment_kmh * 2.8;
      }
    } 
    if(sekund6.available()){
      temp_kmh = temp_kmh + correct_moment_kmh;
      sample++;
      sekund6.restart();
     }
    if(sample==10){
      average_kmh = temp_kmh / 10; 
      temp_kmh = 0;
      sample=0;
      sekund6.restart();
    }
   interrupts() ; //Przywróć przerwania
}
void light(){
  lightSensor->setValue(lightMeter.readLightLevel());
}
void sds(){
  if((minut5.available()) && (startOdczyt ==0)){
    sekund30.restart();
    startOdczyt = 1;
    odczyt = 1;
    my_sds.wakeup();
  }
  if((sekund30.available()) && (odczyt == 1)){
      error = my_sds.read(&p25, &p10);
       if (!error) {
        P2->setValue(p25);
        P10->setValue(p10);
        Serial.println("P2.5: " + String(p25));
        Serial.println("P10:  " + String(p10));
        minut5.restart();
        startOdczyt = 0;
        odczyt = 0;
        my_sds.sleep();
       }
  }
}

void setup() {
   // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {xx};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {xx};
    
      my_sds.begin(rxPin, txPin); //RX, TX
  Serial.begin(9600);
    Wire.begin(SDA_BH, SCL_BH);
    lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire);
    new Supla::Sensor::DHT(dhtPin, DHT22);
    moment_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    average_wind = new Supla::Sensor::GeneralPurposeMeasurement();
    rain = new Supla::Sensor::GeneralPurposeMeasurement();   
    P2 = new Supla::Sensor::GeneralPurposeMeasurement();
    P10 = new Supla::Sensor::GeneralPurposeMeasurement();
    lightSensor = new Supla::Sensor::GeneralPurposeMeasurement();
    new AnalogValue(analogInPin);
    pinMode(windPin,INPUT_PULLUP);
    pinMode(rainPin,INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(rainPin), rn, RISING); 
    attachInterrupt(digitalPinToInterrupt(windPin), rpm_fan, FALLING);
    minut5.begin(299999);
    sekund30.begin(30001);
    minuta.begin(59999);
    sekund6.begin(6000);
    sekund1.begin(1000);
    last_event = millis();
    last_event1 = millis();
       SuplaDevice.begin(GUID,              // Global Unique Identifier 
                    "svrxx.supla.org",  // SUPLA server address
                    "[email protected]",   // Email address used to login to Supla Cloud
                    AUTHKEY);          // Authorization key
}

void loop() {
    SuplaDevice.iterate();
    temporaryRPM();
    sendSupla();
    sds();
}
void sendSupla(){
    if(sekund1.available()){  
      moment_wind->setValue(correct_moment_kmh);
      sekund1.restart();
    }
    if(minuta.available()){  
      light();
      mmM2=rai*0.15; // dwa przerwnia na jedną kolebkę, więc 0.15
      rain->setValue(mmM2);
      average_wind->setValue(average_kmh);
      rai=0;
      minuta.restart();
    }
}
Sprawdź to. Program się kompiluje, ale sprawdź działanie bo nie mam takich czujników.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Bernix
Posts: 93
Joined: Tue Jan 03, 2023 10:29 am

Post

Oki. Dziękuję. Gdzie się tego wszystkiego można nauczyć :D .
User avatar
YoMan
Posts: 3521
Joined: Thu Apr 30, 2020 5:18 pm
Location: Częstochowa
Has thanked: 3 times
Been thanked: 3 times

Post

Bernix wrote: Tue Nov 26, 2024 7:49 am Oki. Dziękuję. Gdzie się tego wszystkiego można nauczyć :D .
Właśnie jesteś w najlepszym miejscu: Collegium Suplum scientiarum :ugeek:
YoMan
________________________________________
Wziąłem udział w SOP2023 & SOP2024
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Bernix wrote: Tue Nov 26, 2024 7:49 am Oki. Dziękuję. Gdzie się tego wszystkiego można nauczyć :D .
Ja jestem zupełnym amatorem, hobbystą. Niewiele umiem, ale na moje potrzeby mi wystarcza, a zawsze można zapytać to tu to tam;).
Jeślibyś naprawdę chciał spróbować to polecam:
https://forbot.pl/blog/kursy
a na początek choćby to:
https://forbot.pl/blog/kurs-arduino-pod ... rsu-id5290
Takie też były moje początki z forbotem. Szczerze polecam.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79

Return to “Projekty użytkowników”