Skocz do zawartości

Ćwiczenia z Arduino nano, zagadnienia, problemy.


Pomocna odpowiedź

@ethanak Temperatura to najmniejszy problem jest w tej chwili, bo to do niczego ten pomiar nie będzie wchodzić. (Orientacyjne wskazanie).

sensors.setWaitForConversion(0);
      sensors.requestTemperatures();
      odczyt_temp = sensors.getTempCByIndex(0)

Na razie mam to zrobione w ten sposób i działa. Przy przechodzeniu case nie sypie 85C. Wypróbuję też Twoją opcję. 

Pomysł z tą inicjacją begin w pętli loop jest dobry, ale tylko wtedy jak chcesz podłączyć kilka czujników DS do oddzielnych portów.  Być może jest jakaś inna opcja, ale wymaga dokładnej analizy biblioteki.  

 

31 minut temu, ethanak napisał:

Poza tym tu masz zakończenie sygnalizacji po iluś tam sekundach

Tzn. Mam to zrobione to poprzez licznik cykli. Sekund jest tylko 6, a licznik na 50 co daje 5min. To są 3 mignięcia na 3 sekundy przerwy = cykl. 

 

 Zrobiłem built tych dwóch szkiców, i powoli eliminuję konkretne byki przez duże "B" (w tym czysto techniczne). XD.

22 minuty temu, ethanak napisał:

 Po pierwsze nawiasy nie gryzą

Ok. warto zapamiętać. (poprawię od ręki) 🙂

Zrobię całość, to się dalej będziemy zastanawiać. 

 

22 minuty temu, rafal220 napisał:

Być może jest jakaś inna opcja, ale wymaga dokładnej analizy biblioteki. 

Nie, nie analizy a myślenia.

Czy jeśli masz dwa balkony np. jeden od północy, drugi od południa to musisz przenosić termometry? Czy może trzeba przykręcić dwa?

Dlaczego uważasz, że może istnieć tylko jeden obiekt OneWire i tylko jeden DallasTemperature?

 

10 minut temu, ethanak napisał:

Dlaczego uważasz, że może istnieć tylko jeden obiekt OneWire i tylko jeden DallasTemperature?

Bo jeszcze nie obczajam dokładnie tych funkcji. Co ja się ukombinowałem aby zadeklarować kilka wejść na kilka czujników. Nie chcę jednej linii, bo padnie jeden czujnik (zrobi zwarcie) i jest lipton. Deklaracja kilku onewire albo I2C czy też SPI (np. w przypadku ESP S2), to podstawa która powinna być omówiona w kursie na forbocie. 🙂

@ethanak No ale skoro zakres Arduino obejmuje ESP, to warto przeżyć kurs o nowe horyzonty. Ponadto miała powstać III część. Ja jestem za. Na tych mega328 za wiele nie zrobi. Wiesz ile zajmuje ten mój skromny program do klikania przekaźnikiem? 60%. A w C3 w ogóle nie widać zużycia pamięci pomijając te 20% zarezerwowanych dla "pasożyta" 

(edytowany)

Wstępny builit docelowego programu. 

//************************************Inicjacja biblioteki cz. temp. DS18B20*************************************************
#include <OneWire.h>
#include <DallasTemperature.h>

OneWire oneWire(10);
DallasTemperature sensors(&oneWire);
//***************************************************************************************************************************

//***********************************Inicjacja biblioteki wyświetlacza OLED SSD1315 (128x64)**********************************
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // Szerokość wyświetlacza OLED w pikselach
#define SCREEN_HEIGHT 64  // Wysokość wyświetlacza OLED w pikselach

#define OLED_RESET -1        // Bez pinu RST
#define SCREEN_ADDRESS 0x3C  // Adres wyświetlacza
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//****************************************************************************************************************


#define przycisk 3
#define przekaznik 4
#define sygnalizacja_LED 5

bool przycisk_status, przekaznik_status, sygnalizacja_LED_status, awaria_cewki = 0;
int czas_zal = 1200;
int prad_cewki, rezystancja_cewki, napiecie, napiecie_cewki;
unsigned int TT;  // Zmienna globalna millis
//-----------------------------------------------------------------------------------------------------------------------

const int MAX_rezystancja = 105;  // Dopuszczalne wartości rezystancji cewki
const int MIN_rezystancja = 80;

//-----------------------------------------------------------------------------------------------------------------------

void setup() {

  pinMode(przycisk, INPUT_PULLUP);
  pinMode(przekaznik, OUTPUT);
  pinMode(sygnalizacja_LED, OUTPUT);

  sensors.begin();  // Uruchamianie cz. DS18B20

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);  // Uruchamianie OLED 128 x 64
  display.clearDisplay();
}

void loop() {

  TT = millis();  // Główny zegar systemowy millis "TT"

  //----------------------------------------------------------------------------------------------------
  prad_cewki = map(analogRead(A1), 0, 4095, 1, 300);  //Konwersja wartości analogowych
  napiecie_cewki = map(analogRead(A0), 0, 4095, 0, 30000);
  rezystancja_cewki = napiecie_cewki / prad_cewki;
  rezystancja_cewki = min(rezystancja_cewki, 999);
  //----------------------------------------------------------------------------------------------------

  digitalWrite(przekaznik, !przekaznik_status);
  digitalWrite(sygnalizacja_LED, !sygnalizacja_LED_status);

  //************************************Inicjacja funkcji*******************************************
  funkcja_przycisk();

  funkcja_przekaznik();

  funkcja_sygnalizacja_LED();

  Funkja_wyswietlacz_SSD1315();
}

//****************************************Funkcja przycisk*****************************************
int funkcja_przycisk() {

  static unsigned int t0, t1 = 0;

  if (digitalRead(przycisk) == 0) {
    t0 = TT - t1;
    if (t0 > czas_zal) { przycisk_status = 1; }  // opóźnione załączenie
  } else {
    t1 = TT;
    przycisk_status = 0;
  }
  return przycisk_status;
}
//*************************************************************************************************

//*****************************************Funkcja przekaznik***************************************
int funkcja_przekaznik() {

  static bool test_cewki, prad_ok, d0, d1 = 0;
  static unsigned int t0, t1 = 0;

  //----------------------------------------------------------------------------------------------
  if ((przycisk_status == 1) && (awaria_cewki == 0)) {
    t0 = TT - t1;
    if (t0 < 500) {
      test_cewki = 1;
    } else {
      test_cewki = 0;
    }

    if (((t0 > 400) && (rezystancja_cewki > MAX_rezystancja) && (przekaznik_status == 1)) ||
          ((t0 > 400) && (rezystancja_cewki < MIN_rezystancja) && (przekaznik_status == 1))) {
          test_cewki = 0;
          awaria_cewki = 1;  // Test cewki 400ms
    }
  } else {
    t1 = TT;
    test_cewki = 0;
  }
  Serial.println(czas_zal);
  Serial.println(prad_cewki);
  //-------------------------------------------------------------------------------------------------
  if ((rezystancja_cewki < MAX_rezystancja) && 
      (rezystancja_cewki > MIN_rezystancja) || (test_cewki == 1)) {  // Pomiar prądu cewki zaworu
       prad_ok = 1;
  } else {
    przekaznik_status = 0;
    prad_ok = 0;
    czas_zal = 1200;
  }
  //-----------------------------------------------------------------------------------------------

  if ((prad_ok == 1) && (przycisk_status == 1) && (awaria_cewki == 0)) {
    przekaznik_status = 1;
  } else if ((przycisk_status == 0) && (przekaznik_status == 1)) {  // Włączenie cewki zaworu
    d0 = 1;
    czas_zal = 100;
  }
  if ((przycisk_status == 1) && (d0 == 1)) {  // Wyłączenie cewki zaworu
    przekaznik_status = 0;
  } else if ((przekaznik_status == 0) && (d0 == 1)) {
    d0 = 0;
  }
  return przekaznik_status;
}

//************************************************************************************************************

//***********************************Funkcja sygnalizacji pracy i awarii**************************************
int funkcja_sygnalizacja_LED() {

  static int i0 = 0;
  static unsigned int t0, t1 = 0;

  if (przekaznik_status == 1) {
    sygnalizacja_LED_status = 1;  // Sygnalizacja LED pracy cewki
  } else {
    sygnalizacja_LED_status = 0;
  }

  if ((awaria_cewki == 1) && (i0 < 50)) {  // Sygnalizacja awarii cewki
    t0 = TT - t1;
    if ((t0 < 600) || (t0 > 1200) && (t0 < 1800) || (t0 > 2400) && (t0 < 3000)) {
      sygnalizacja_LED_status = 1;
    }
    if ((t0 > 600) && (t0 < 1200) || (t0 > 1800) && (t0 < 2400) || (t0 > 3000)) {
      sygnalizacja_LED_status = 0;
    }
    if (t0 > 6000) {
      sygnalizacja_LED_status = 0;
      t1 = TT;
      ++i0;  // Zakończ sygnalizację awarii po 5min.
    }
  } else {
    t1 = TT;
    i0 = 0;
    awaria_cewki = 0;
  }
  return sygnalizacja_LED_status;
}
//********************************************************************************************************************************************

//******************************************************Funkja wyświetlacz SSD1315 (128x64)***************************************************

int Funkja_wyswietlacz_SSD1315() {
  static int ret = 0;
  static int napiecie_1, napiecie_01, napiecie_001 = 0;
  static int prad_1, prad_01, prad_001 = 0;
  static int rezystancja_1, rezystancja_01, rezystancja_001 = 0;
  static int temperatura_1, temperatura_01, temperatura_001 = 0;
  static float odczyt_temp = 0;
  static int temperatura = 0;
  static unsigned int t0, t1 = 0;

  t0 = (TT - t1) / 100;
  //--------------------------------------------------------------------------------------------------------------------------------------
  switch (t0) {
    case 1:
      napiecie = napiecie_cewki / 100;
      napiecie_1 = napiecie / 100;
      napiecie_01 = (napiecie % 100) / 10;  // Wskazanie napięcia
      napiecie_001 = napiecie % 10;

      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 0);
      display.setTextColor(WHITE, BLACK);
      display.println(F("  VOLTAGE  "));
      display.setTextSize(4);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(6, 27);
      display.setTextColor(WHITE, BLACK);
      if (napiecie_1 > 0) {
        display.print(napiecie_1);
      } else {
        display.print(' ');
      }
      display.print(napiecie_01);
      display.print('.');
      display.print(napiecie_001);
      display.print('V');
      display.display();
      break;
      //------------------------------------------------------------------------------------------------------------------------
    case 26:
      prad_1 = prad_cewki / 100;
      prad_01 = (prad_cewki % 100) / 10;  // Wskazanie prądu
      prad_001 = prad_cewki % 10;

      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 0);
      display.setTextColor(WHITE, BLACK);
      display.println(F("  CURRENT  "));
      display.setTextSize(4);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(6, 27);
      display.setTextColor(WHITE, BLACK);
      display.print(prad_1);
      display.print('.');
      display.print(prad_01);
      display.print(prad_001);
      display.print('A');
      display.display();
      break;
      //------------------------------------------------------------------------------------------------------------------------
    case 46:
      rezystancja_1 = rezystancja_cewki / 100;
      rezystancja_01 = (rezystancja_cewki % 100) / 10;  // Wskazanie rezystancji
      rezystancja_001 = rezystancja_cewki % 10;

      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(4, 0);
      display.setTextColor(WHITE, BLACK);
      display.println(F("RESISTANCE"));
      display.setTextSize(4);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(6, 27);
      display.setTextColor(WHITE, BLACK);
      if (rezystancja_1 > 0) {
        display.print(rezystancja_1);
      } else {
        display.print(' ');
      }
      display.print(rezystancja_01);
      display.print('.');
      display.print(rezystancja_001);
      display.print('R');
      display.display();
      break;
    //----------------------------------------------------------------------------------------------------------------------
    case 66:
      sensors.setWaitForConversion(0);
      sensors.requestTemperatures();
      odczyt_temp = sensors.getTempCByIndex(0) * 10;
      temperatura = odczyt_temp;  // konwersja float > int

      temperatura_1 = temperatura / 100;
      temperatura_01 = (temperatura % 100) / 10;  // Wskazanie temperatury
      temperatura_001 = temperatura % 10;

      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(6, 0);
      display.println(F(" TEMPERAT"));
      display.setTextSize(3);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(25, 30);
      if (temperatura_1 > 0) {
        display.print(temperatura_1);
      } else {
        display.print(' ');
      }
      display.print(temperatura_01);
      display.print('.');
      display.print(temperatura_001);
      display.print('C');
      display.display();
      break;

    default:
      if (t0 > 86) { t1 = TT; }
  }
  return ret;
}

Będę jeszcze testować na wszystkie możliwe sposoby. Czyli wciskasz, kręcisz, wciskasz i kręcisz na raz etc. Wiecie jak się robi takie testy na bugi. XD A i tak zawsze z czasem wychodzi... 

Edytowano przez rafal220
3 minuty temu, rafal220 napisał:

zakres Arduino obejmuje ESP

Coś Ci się pozajączkowało chyba.

Arduino board dla ESP32 jest dziełem Espressifa a nie Arduinowców. I jest to rozszerzenie o dodatkowe rzeczy, które są dokładnie opisane w dokumentacji owej firmy dotyczącej programowania ESP32 używając frameworka Arduino.

Poza tym można używać również funkcji FreeRTOS, jak i tych pochodzących z idf.

A poza tym istnieje wiele płytek które moż na programować w Arduino - ESP8266, RP2040, różne STM-y, pewnie jeszcze parę o których nie słyszałem. Taki twój wymarzony "kurs" obejmujący "wszystko" to sprawa całkowicie nierealna. Przecież nawet opis C to gruba książka, C++ kilka razy grubsza, nie ma szans żeby omówić to w jakimś kursie.

A możliwość zadeklarowania kilku zmiennych chyba nie wymaga tłumaczenia "tak się deklaruje jedną zmienną, tak dwie, tak trzy, tak cztery i tak dalej".

Tak jak z kursem na prawko - po skończeniu kursu jesteś w stanie od biedy dojechać z punktu A do punktu B. Ale nie tam nie ma o jeździe po pustyni terenówką, o jeździe śmieciarką po wąskich uliczkach czy dragsterach.

Chodzi o zjawisko szumów łączeniowych? To ja mam swój prosty kod który umożliwia dodatkowo funkcję delay opartą na millis. No niestety w tym kodzie powyżej nie mogłem tego zastosować, a zjawisko drgań jest eliminowane przy okazji po drodze. Zerknij na kod. Wstawiłem cały built. 

Co do arduino, to nie oczekuję, że jeden kurs wszystko załatwi. Mam na myśli to, aby powstała III część na podbudowie innej architektury. Np. ESP. 

16 minut temu, rafal220 napisał:

Mam na myśli to, aby powstała III część na podbudowie innej architektury. Np. ESP. 

Ale ESP8266 czy ESP32?, A jeśli 32 to które? I dlaczego nie RP2040?

Powtarzam: to już nie byłby kurs Arduino. W trzeciej części lepiej wprowadzić trochę więcej o C++, a nie rozbijać się na konkretne architektury. Zdajesz sobie w ogóle sprawę z tego, że taki "kurs Arduino w ESP" miałby kilkaset rozdziałów, powstawałby pewnie parę lat i gdzieś w połowie przestałby być aktualny. A może kursy na prawo jazdy wzbogacić o jazdę śmieciarką?

A co do linijek - porównaj:

    if (((t0 > 400) && (rezystancja_cewki > MAX_rezystancja) && (przekaznik_status == 1)) || ((t0 > 400) && (rezystancja_cewki < MIN_rezystancja) && (przekaznik_status == 1))) {

i na przykład:

    if (((t0 > 400) &&
         (rezystancja_cewki > MAX_rezystancja) && 
         (przekaznik_status == 1)) || 
        ((t0 > 400) && 
          (rezystancja_cewki < MIN_rezystancja) &&
          (przekaznik_status == 1))) {

Dzielisz tam gdzie jest sens, a wcięcia pomagają w czytelności.

Ok. dzięki. Zaktualizuję kod. Zwłaszcza że pojawiły się kolejne bugi w czasie majtania stanami logicznymi. Taki to jest już tego urok. Zresztą dla mnie to żadna nowość szukania i łatania dziur programowych. Tutaj to pół biedy, ale weź się dla przykładu porządnie rypnij w logice CMOS albo TTL? Na PCB nie zawsze można sobie coś przeciąć albo dolutować. XD

Mam taki kawałek kodu;

//*************************************Funkcja test kontrolek**************************************
void funkcja_test_LED() {

static bool d0 = 1;

while ((analogRead(A3) < 1000) && (d0 == 1)){ 
  digitalWrite(sygnalizacja_LED, !HIGH);
delay(1500);

if(analogRead(A3) > 1000) {
  digitalWrite(sygnalizacja_LED, !LOW);
  d0 = 0;
  break;
}
while(true){

      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 0);
      display.println(F("SPRAWDZ"));
      display.println(F("KONTROLKI"));
      display.println(F("PULPIT"));
      display.println(F("PRZYCISK"));
      display.display(); 

      digitalWrite(sygnalizacja_LED, !LOW);
      digitalWrite(przekaznik, !LOW);
      delay(100);
}
}
 }

Co zrobić aby po wejściu do while pętla widziała zmienną globalną np. prad_LED aby nie było konieczności bezpośredniego odnoszenia do analogRead?

to samo z digitalWrite. 

5 minut temu, rafal220 napisał:

Co zrobić aby po wejściu do while pętla widziała zmienną globalną np. prad_LED aby nie było konieczności bezpośredniego odnoszenia do analogRead?

Ktoś chyba pomylił klocki z mikroprocesorami... Bez analogRead zmienna globalna w pętli będzie zawsze miała stałą wartość, więc to nie będzie działało tak jak chcesz. Chyba, że ja coś źle rozumiem Twoją definicję "zmiennej globalnej".

Jedyna "opcja" to zmienna globalna, która jest przypisywana w czasie działania pętli.

1 minutę temu, H1M4W4R1 napisał:

Jedyna "opcja" to zmienna globalna, która jest przypisywana w czasie działania pętli.

Czyli sumując da się zrobić tak aby while w czasie działania sprawdzała jakieś zmienne które znajdują się po za jej nawiasem? Bo to co jest na górze działa ok, ale chciałbym aby funkcja widziała zmienne które zadeklarowałem wcześniej pod analogRead etc. 

Przede wszystkim będzie sprawdzać zmienną ale ta będzie cały czas taka sama bo nikt jej nie zmienia a sama się nie zmieni. Rozumiem, że w klockach coś takiego jest możliwe ale zapominasz, że to co widxisz to tylko aplikacja, a procek pod spodem robi różne swoje czynności o których nie wiesz i nie masz do nich dostępu.

A z ciekawości - co przeszkadza analogRead w pętli i po kiego grzyba ta pętla? 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...