Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Multimetr Fluke
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Freeze Arduino przy odłączonym LCD lub funkcją Serial.print

ICEMANIK 11 Nov 2018 19:30 906 41
  • #1
    ICEMANIK
    Level 10  
    Witam,
    w moim Arduino następuje zwis, gdy będzie odłączony LCD 2x16 (zgodny z hd44780). Arduino się włacza, diody zasilania świecą, ale program staje w okolicach inicjalizacji lcd. Czy to normalne? Czy programowo jestem w stanie to obejść np jakimś IF'em?

    Drugi problem, który objawia się tak samo, czyli zwis w miejscu kodu gdzie wywołuję Serial.print. Program wykona funkcje do momentu napotkania Serial.print, a potem freeze :( Zatem już dość długo przeprowadzam doświadczenia "na żywcu" zamiast przez monitor szeregowy co jest dość up... orczywe.
    To wina kodu w Setup?

    Spoiler:
    void setup() { //40ms
    //analogReference(EXTERNAL); //konfiguracja referencyjnego napięcia
    dht.setup(DHT11_PIN); //setup wilgotnosci
    Serial.begin(19200); //start portu COM
    Serial3.begin(9600); //start COM dla BT
    SPI.begin(); //start komunikacji
    pinMode(JoyFx, INPUT); pinMode(JoyFy, INPUT); pinMode(JoyRx, INPUT); pinMode(JoyRy, INPUT);
    pinMode(JoyFs,INPUT_PULLUP);
    pinMode(JoyRs,INPUT_PULLUP);
    pinMode(kompresorpin, OUTPUT);
    pinMode(grzalkapin, OUTPUT);
    pinMode(sport, INPUT);
    pinMode(tour, INPUT);
    pinMode(gleba, INPUT);
    pinMode(climatronic, INPUT);
    pinMode(buzzer, OUTPUT);
    pinMode(DHT11_VCC, OUTPUT);
    pinMode(DHT11_GND, OUTPUT);
    digitalWrite(kompresorpin, HIGH);
    digitalWrite(grzalkapin, HIGH);
    digitalWrite(buzzer, HIGH);
    pinMode(DHT11_VCC, HIGH);
    pinMode(DHT11_GND, LOW);

    //fix dla nieużywanych pinów analogowych by nie robiły zakłóceń
    pinMode(A8, OUTPUT); digitalWrite(A8, LOW);
    pinMode(A9, OUTPUT); digitalWrite(A9, LOW);

    //config pinów zaworów
    for( i = 0; i < 4; i++){
    pinMode(upvalves[i], OUTPUT); digitalWrite(upvalves[i], HIGH);
    pinMode(downvalves[i], OUTPUT); digitalWrite(downvalves[i], HIGH);
    pinMode(crossvalves[i], OUTPUT); digitalWrite(downvalves[i], LOW);
    }

    //config pinów czujników
    //for( i = 0; i < 5; i++){ pinMode(s[i], INPUT_PULLUP); }
    //for( i = 0; i <= 5; i++){ pinMode(s[i], INPUT); }
    pinMode(A1, INPUT_PULLUP);
    pinMode(A2, INPUT_PULLUP);
    pinMode(A3, INPUT_PULLUP);
    pinMode(A4, INPUT_PULLUP);
    pinMode(A5, INPUT_PULLUP);

    //======================= temperatura DS18B20 ====================
    sensors.begin(9);
    sensors.request(address);

    lcd.begin(16, 2); // Wybór rodzaju wyświetlacza - 16x2
    lcd.init(); // Start LCD
    lcd.backlight(); // Lights ON
    lcd.createChar(0, znakdol);
    lcd.createChar(1, znakgora);
    lcd.createChar(2, celcius);
    lcd.createChar(3, bticon);
    lcd.createChar(4, connection);
    lcd.createChar(5, viair);
    lcd.createChar(6, heat);
    lcd.createChar(7, cros);
    lcd.home ();
    lcd.print("Start"); //LCD start up

    tone(buzzer, 1000, 100);delay(100);
    tone(buzzer, 2000, 100);delay(100);
    tone(buzzer, 4000, 100);delay(100);
    tone(buzzer, 6000, 100);delay(500);
    lcd.clear();

    ReadSensors(); //kolejność autostart
    ShowLCDtryb();
    //akcja.attach(0,500, ReadSensors); // odczyt sensorów ciśnienia
    akcja.attach(0,500, ReadTempWyspaSensors); // odczyt temp
    akcja.attach(1,2500, checkAir); // spr czy potrzeba poziomowania
    akcja.attach(2,50, checkBT); // odczyt BT
    akcja.attach(3,90, trybManual); // manual
    akcja.attach(4,2000, sekwencjaLCD); // status sekwencji lcd
    akcja.attach(5,300, ShowLCDtryb); // zrzut trybu na lcd
    akcja.attach(6,110, JoyTrybChange); // sprawdza stan klawisza UP - tryb 150
    akcja.attach(7,60, sterownikGiroBT); //
    }
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Multimetr Fluke
  • #2
    khoam
    Level 40  
    ICEMANIK wrote:
    ale program staje w okolicach inicjalizacji lcd. Czy to normalne? Czy programowo jestem w stanie to obejść np jakimś IF'em?

    Napisz konkretnie, jakiej biblioteki używasz do obsługi wyświetlacza LCD. Na pewno można wykryć brak podłączonego wyświetlacza np. tak:
    Code: c
    Log in, to see the code

    Trzeba znać adres i2C wyświetlacza, zwykle jest to 0x27. Oczywiście to sprawdzanie należy wykonać jeszcze przed lcd.begin().


    ICEMANIK wrote:
    Drugi problem, który objawia się tak samo, czyli zwis w miejscu kodu gdzie wywołuję Serial.print

    Szukałem, ale w przedstawionym kodzie wywołania funkcji Serial.print() nie znalazłem.
  • #3
    arkady_pl
    Level 24  
    Kłopotem jest biblioteka Wire.h.
    Niestety zawiera ona błąd(niedociągnięcie).
    Gdy dochodzi do momenty gdzie czeka na sygnał i go nie dostaje to wisi w pętli while().
    Sprawdź połączenie na kablach.

    Dodano po 1 [minuty]:

    @ICEMANIK czy używasz płytki Arduino Mega2560 czy czegoś mniejszego?
  • Multimetr Fluke
  • #4
    khoam
    Level 40  
    arkady_pl wrote:
    Niestety zawiera ona błąd(niedociągnięcie).
    Gdy dochodzi do momenty gdzie czeka na sygnał i go nie dostaje to wisi w pętli while().


    Naprawdę? Przed chwilą sprawdziłem i Wire.endTransmission() zwrócił mi niezerowy kod przy odłączonym wyświetlaczu dokładnie tak, jak to powinno być.
    Czy mógłby kolega rozwinąć temat tego konkretnego błędu w Wire?
  • #5
    arkady_pl
    Level 24  
    khoam wrote:
    arkady_pl wrote:
    Niestety zawiera ona błąd(niedociągnięcie).
    Gdy dochodzi do momenty gdzie czeka na sygnał i go nie dostaje to wisi w pętli while().


    Naprawdę? Przed chwilą sprawdziłem i Wire.endTransmission() zwrócił mi niezerowy kod przy odłączonym wyświetlaczu dokładnie tak, jak to powinno być.
    Czy mógłby kolega rozwinąć temat tego konkretnego błędu w Wire?


    Być może dysponujesz biblioteką z poprawką. W wersjach Arduino IDE 1.6.5 i wcześniej nie było poprawek.

    Zatem jeśli staje dęba to pytanie moje, które napisałem wczesniej, "jaką płytkę ma autor?" Arduino Mega2560 czy np. UNO. Bo W programie jest odwołanie Serial3.....
  • #7
    ICEMANIK
    Level 10  
    khoam,
    biblioteka to , mam kilka takich lcd i akurat ten którego używam tylko z tą chciał gadać:
    #include <LiquidCrystal_I2C.h> // I2C dla LCD

    khoam wrote:
    Trzeba znać adres i2C wyświetlacza, zwykle jest to 0x27

    u mnie jest 0x3F, dziękuję, właśnie czegoś takiego szukałem, widac słabo, sprawdzę czy pomoże.

    khoam wrote:
    Szukałem, ale w przedstawionym kodzie wywołania funkcji Serial.print() nie znalazłem.

    zgadza się, wywaliłem wszystkie, nie dało rady odpalić programu. W zasadzie nie ważne gdzie wstawię printa będzie zwis :(
    arkady_pl wrote:
    Kłopotem jest biblioteka Wire.h.
    Niestety zawiera ona błąd(niedociągnięcie).
    Gdy dochodzi do momenty gdzie czeka na sygnał i go nie dostaje to wisi w pętli while().
    Sprawdź połączenie na kablach.

    Rzeczywiście biblioteki ściągałem rok temu i później ich nie aktualizowałem. To może być to. Tak wiem, że wina kabli, ale LCD u mnie to tylko dodatek, którego w razie "awarii przewodów LCD" nie potrzebuję do działania programu "w trybie awarii" - projekt jeździ w aucie od wiosny i co rusz kara mnie błedami nowicjusza :)

    arkady_pl wrote:
    czy używasz płytki Arduino Mega2560 czy czegoś mniejszego?

    tak, klon Mega na pokładzie, używam Arduino IDE 1.8.4
  • #8
    arkady_pl
    Level 24  
    Odnośnie "stawania dęba" to można zrobić test z użyciem diody LED i jednego pinu binarnego. Wystarczy włączać ledę pop przejściu zadanego punktu "pułapki". Jeśłi leda nie zaświeci się to przesuwamy o jedną linię wcześniej. I w ten sposób dokładnie ustalamy miejsce.

    Biblioteki potrafią się zakócać. Ja dzisiaj odkryłem, że u mnie biblioteka od wyświetacza OLED na SSD1306 na i2C kłóci się z bibioteką LiquidCrystal_I2C i nie mogę spiąc obu ekranów razem. I też szukam miejsca kolizji.

    Także najpierw Autor jest proszony o dokładne ustalenie punktu zatrzymania.
  • #9
    khoam
    Level 40  
    ICEMANIK wrote:
    biblioteka to , mam kilka takich lcd i akurat ten którego używam tylko z tą chciał gadać:
    #include <LiquidCrystal_I2C.h> // I2C dla LCD


    Podaj może autora tej biblioteki albo jakiś link, bo o tej nazwie jest kilka bibliotek.

    Dodano po 5 [minuty]:

    arkady_pl wrote:
    Biblioteki potrafią się zakócać. Ja dzisiaj odkryłem, że u mnie biblioteka od wyświetacza OLED na SSD1306 na i2C kłóci się z bibioteką LiquidCrystal_I2C i nie mogę spiąc obu ekranów razem.


    A sprawdzałeś faktyczne adresy i2c za pomocą skanera?

    Dodano po 5 [minuty]:

    ICEMANIK wrote:
    W zasadzie nie ważne gdzie wstawię printa będzie zwis


    Akurat to jest ważne. Najlepiej zacząć od początku w setup() :)
  • #10
    ICEMANIK
    Level 10  
    khoam wrote:
    Podaj może autora tej biblioteki albo jakiś link, bo o tej nazwie jest kilka bibliotek.


    Dopiero 7-8-ma biblioteka mi ruszyła, niestety nie pamiętam skąd, podaje ją w załączniku.

    khoam wrote:
    Akurat to jest ważne. Najlepiej zacząć od początku w setup()

    Dobra, sprawdzę i to :)
  • #11
    khoam
    Level 40  
    ICEMANIK wrote:
    Dopiero 7-8 biblioteki mi ruszyła, niestety nie pamiętam skąd, podaje ją w załączniku


    Pechowo wybrałeś, ta biblioteka jest stąd - nie jest rozwijana, brak w kodzie jakiejkolwiek obsługi błędów.

    Nie bardzo chce mi się wierzyć, że tak wiele bibliotek nie chciało współpracować z Twoim wyświetlaczem. Jaki tam jest zainstalowany expander I2C? PCF8574 czy coś innego?
  • #12
    ICEMANIK
    Level 10  
    tak, PCF8574. Najpierw programowałem na niebieskim lcd, potem ostatecznie przyszedł czarny i na nim nie chciała ruszyć żadna biblioteka, oprócz tej załączonej, wtedy nauczyłem się odczytywać adres lcd :) Gdyby to był mój pierwszy uruchamiany lcd to pewnie rzuciłbym całe to arduino w kąt, ale od roku walczę dalej :)
  • #13
    khoam
    Level 40  
    Używam bibioteki LiquidCrystal_PCF8574. Na razie mnie nie zawiodła. Wymaga podania adresu i2c w konstruktorze.

    Używałem również biblioteki hd44780. Też się u mnie sprawdziła. Automatycznie wykrywa adres i2c wyświetlacza i ma wsparcie do automatycznego ładowania własnych znaków z PROGMEM. Jest również ładnie napisana w C++ oraz zajmuje za dużo miejsca w pamięci, jak dla mnie :)

    Dodano po 56 [sekundy]:

    ICEMANIK wrote:
    ostatecznie przyszedł czarny


    A skąd masz ten czarny wyświetlacz? Chętnie bym się w taki zaopatrzył.
  • #14
    ICEMANIK
    Level 10  
    khoam wrote:
    A skąd masz ten czarny wyświetlacz? Chętnie bym się w taki zaopatrzył.

    wszystko od majfrendów tylko trzeba być cierpliwym, aczkolwiek ten udało się z portalu aukcyjnego bo cena przystępna.
  • #15
    ICEMANIK
    Level 10  
    Jak mam rozumieć linijkę?
    khoam wrote:
    if (Wire.endTransmission() != 0) {

    Jeżeli transmisja zakończona różna od zera to "nie ma lcd"? Czemu to jest negacja?
    w klamrach mam ustawić status dla lcd by później przy wywołaniu lcd.print najpierw sprawdzać czy ten status jest true przez printem?

    Edit: OK, już znalazłem:
    "Returns: byte, which indicates the status of the transmission:
    0: success
    1: data too long to fit in transmit buffer
    2: received NACK on transmit of address
    3: received NACK on transmit of data
    4: other error"
  • #16
    khoam
    Level 40  
    Tak, jak napisałem wcześniej:
    - jeżeli endTransmission() zwraca wartość różną od zera (kod błędu), to znaczy, że jest problem w komunikacji z wyświetlaczem lub jego brak
    - ten test przeprowadza się tylko przed przed lcd.begin() - jeżeli nie ma wyświetlacza to jakiekolwiek dalsze komendy do lcd po lcd.begin() nie mają sensu
  • #17
    ICEMANIK
    Level 10  
    tak, zgadza się. Już doczytałem o co chodzi. Funkcja ta zwraca flagę dla magistrali I2C.

    Wracając to tematu zwiechy Arduino gdy odłączymy lcd lub gdy damy serial.print. Usunąłem znaczną część kodu, zostawiłem Setup w oryginale a w Loop'ie dałem tylko Serial printa. Efektem jest, że Arduino działa jak należy, żatem zacząłem kopać dalej i odnalazłem linijkę w która powoduje zamrożenie Arduino. Jest nią sama pętla "for", która nawet pusta zawiesi Arduino. Nie wiem czemu sie tak dzieje, podobnych pętli używam w wielu miejscach.

    Spoiler:
    void strzalki() {
    //SAMO WYWOŁANIE PUSTEJ PETLI FOR POWODUJE BŁĄD SERIAL.PRINT I ZAWIECHE ARDUINO :(
    for( i = 0; i <= 3; i++){
    //if (zaworykod.substring(i,i+1) == "1") {lcd.setCursor(svallcdx[i]+1, svallcdy[i]);lcd.print(char(1));} // open up
    //if (zaworykod.substring(i+4,i+5) == "1") {lcd.setCursor(svallcdx[i]+1, svallcdy[i]);lcd.print(char(0));} // open down
    //if (zaworykod.substring(i,i+1) == "0") {lcd.setCursor(svallcdx[i]+1, svallcdy[i]);lcd.print("."); } // close up
    //if (zaworykod.substring(i+4,i+5) == "0") {lcd.setCursor(svallcdx[i]+1, svallcdy[i]);lcd.print("."); } // close down
    }
    }
    [/spoiler]
  • #19
    ICEMANIK
    Level 10  
    khoam wrote:
    A zmienna i jakiego jest typu w tej pętli for?

    typu byte

    testując dalej odkryłem, że wyprintowanie jakiejkolwiek zmiennej powoduje problem.
    Gdy printuję tekst np "xxx" zamiast zmiennej sval[i] to program hula,
    ale gdy printuję liczbę 1 (Serial.println(1);) zamiast zmiennej sval[i] to program się zawiesi, nawet jeśli ją tymczasowo ustawię jako float. Nic z tego nie rozumiem.

    Spoiler:

    void ReadSensors(){
    for (i=0; i <= 4; i++){
    int pomiar = analogRead(s[i])+scorr[i];
    //Serial.println(pomiar); //tu będzie błąd
    pomiar = map(pomiar,150,1023,0,99);//*1173/1023;
    pomiar = max(min((pomiar),99),0);
    spomiar[i] = (alfa * spomiar[i]) + ((1 - alfa) * pomiar);
    sval[i] = spomiar[i];
    //Serial.println(sval[i]); //to wyświetli 5x
    }
    //Serial.println(sval[i]);
    Serial.println("koniec odczytu"); //to wyświetli raz i kolejnego printa już nie wykona
    Serial.println("test1"); //tego utnie
    }

    Wynik z monitora szeregowego będzie:
    "go
    39
    39
    39
    39
    39
    koniec odczytu
    te"



    Czemu potrafi uciąć w połowie słowo "test1"??

    Zwiększając bitrate z 9600 na 115200 widać, że zdążyło wykonać 1,5x program, a nie jak wcześniej 0,5x . Gdy dam na 250000 wtedy wykona dwie pętle programu. Wygląda na jakieś przepełnienie czegoś, bufora?

    Spoiler:
    go
    1032
    1
    1023
    1
    1032
    1
    1023
    1
    1041
    1
    0
    koniec odczytu
    test1
    zrzut sensor
    1033
    1
  • #20
    khoam
    Level 40  
    ICEMANIK wrote:
    typu byte

    To jeżeli i nie jest jakąś zmienną globalną, powinno być: for (byte i=0; i <= 4; i++)

    Co do reszty, to trochę wygląda mi to na problem z zajętością pamięci SRAM albo z samym portem szeregowym.

    Do zweryfikowania zajętości pamięci SRAM w trakcie działania programu używam MemoryFree.
  • #21
    ICEMANIK
    Level 10  
    Ok, Na pewno mój kod wymaga optymalizacji typu jak wspomniałeś, ale sprawdziłem tym programem co podlinkowałeś, użyłem funkcji freeRam(), Serial print nie chciał gadać, więc zrzuciłem wynik na LCD, pokazuje 6820 tylko nie wiem czy to jest wolne czy zajęte. Ale raczej wolne bo po zakończeniu pierwszej pętli spada z wartości 6860.

    Jeżeli to port szeregowy jest zawalony to sie tak zastanawiam, przez co? Ponieważ w związku z tym, że prawie żaden Serial.print nie działa więc normalnie nie używam w programie żadnego w programie. Chyba, że coś innego go zajmuje... Pytanie gdzie szukać.
  • #22
    khoam
    Level 40  
    ICEMANIK wrote:
    kod wymaga optymalizacji typu

    Nie chodzi tu o optymalizację typu, ten typ w deklaracji zmiennej i powinien być podany chyba, że zmienna i jest zadeklarowana wcześniej jako globalna.

    ICEMANIK wrote:
    użyłem funkcji freeRam()

    Powinieneś użyć getFreeMemory() zgodnie z przykładem zawartym w tej bibliotece.

    ICEMANIK wrote:
    Pytanie gdzie szukać.

    No cóż dopóki nie udostępnisz całego kodu, a przede wszystkim tego co masz zdefiniowane przed setup() to na razie jest to trochę strzelanie w ciemno :)
  • #23
    ICEMANIK
    Level 10  
    khoam wrote:
    chyba, że zmienna i jest zadeklarowana wcześniej jako globalna.

    tak, jest globalna, w zasadzie większość zmiennych mam globalne i właśnie mi o to chodziło, że nie które mógłbym zmienić na lokalne.


    khoam wrote:
    Powinieneś użyć getFreeMemory()

    dobrze, wstawiłęm rozmiar "int size = 8192" dla Mega, wtedy wynik to 6694, gdybym zostawił 2048, wtedy wynik to 2047.

    khoam wrote:
    No cóż dopóki nie udostępnisz całego kodu, a przede wszystkim tego co masz zdefiniowane przed setup() to na razie jest to trochę strzelanie w ciemno

    Jasne, poniżej moje wypociny zmienne + setup. Jeżeli potrzeba wkleję cały kod.
    Z góry dziękuję za pomoc.

    Spoiler:
    /* Wersja v18 beta
    * 2018-11-08

    MPU6050 - adres to 0x68
    i=punkty pomiaru ciśnienia
    FL=0;
    FR=1;
    RL=2;
    RR=3;
    butla=4;
    napięcie=5;
    temp.wyspy=6;

    tryb - tryby pracy mikrokontrolera
    0=manual;
    1=3,2 BAR
    2=3,8 BAR
    3=4,3 BAR
    4=4,8 BAR
    5=6,0 BAR
    6=0,0 BAR
    7=BT manual

    PIN MEGA:
    ANALOG A15:
    0
    1 in czujnik FL x
    2 in czujnik FR x
    3 in czujnik RL x
    4 in czujnik RR x
    5 in czujnik butla x
    6
    7 in napiecie akumulator (dzielnik napiecia) x
    8
    9
    10 in Joy R, os y x
    11 in Joy R, os x x
    12 in przycisk Joy R x
    13 in Joy F, os y x
    14 in Joy F, os x x
    15 in przycisk Joy F x



    Digital D53
    0
    2 in sygnal cyfrowy czujnik temperatury ds18b20 x
    3 in pin przycisku sport x
    4 in pin przycisku tour x
    5 in pin przycisku trakcja x
    6 in pin napiecie konsola w aucie x
    7
    8 in sygnal dla czujnika wilgotnosci dht11 x
    9 out VCC dla czujnika wilgotnosci dht11 x
    10 out GND dla czujnika wilgotnosci dht11 x
    11
    12
    13
    14 com rx bluetooth x
    15 com tx bluetooth x
    16
    17
    18
    19
    20 out i2c, sda komunikacja z lcd x
    21 out i2c, scl komunikacja z lcd x
    22 out buzzer glosnik przy lcd x
    23
    24 out zawor up FL x
    25
    26 out zawor down FL x
    27
    28 out zawor up FR x
    29
    30 out zawor down FR x
    31
    32 out zawor up RL x
    33
    34 out zawor down RL x
    35
    36 out zawor up RR x
    37
    38 out zawor down RR x
    39
    40 out pin zalaczania kompresora x
    41
    42 out pin zalaczania podgrzewania x
    43
    44
    45
    46
    47
    48
    49
    50 out pin sterowania zawór krzyzowy x
    51 out pin sterowania zawór krzyzowy x
    52 out pin sterowania zawór krzyzowy x
    53 out pin sterowania zawór krzyzowy x
    SDA in zyroskop x
    SCL in zyroskop x
    */

    // LCM1602 & Arduino mEGA * VCC - > 5 V * GND - GND * SCL -> SCL * SDA -> SDA
    #include <Wire.h> // standardowa biblioteka Arduino
    #include <LiquidCrystal_I2C.h> // I2C dla LCD
    #include <Timers.h> // biblioteka Timers
    #include <SPI.h> // obsługa komunikacji RFID
    #include <OneWire.h> // obsługa 1wire - temperatura DS18B20
    #include <DS18B20.h> // obsługa czujnika temperatury DS18B20
    #include "DHT.h" // obsługa czujnika wilgotności DHT11

    Timers <6> akcja; // x niezależnych wątków (procesów, zadań, procedur, akcji itp.)
    LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address to 0x27 or 0x3F for a 16 chars and 2 line display
    //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Ustawienie adresu ukladu na BLUELCD

    byte znakdol[8] = {0b11100, 0b10100, 0b10111, 0b10010, 0b10100, 0b11000, 0b10000, 0b00000};
    byte znakgora[8] = {0b10000, 0b11000, 0b10100, 0b10010, 0b10111, 0b10100, 0b11100, 0b00000};
    byte celcius[8] = {0b11000, 0b11000, 0b00111, 0b01000, 0b01000, 0b01000, 0b00111, 0b00000};
    byte bticon[8] = {0b00100, 0b01110, 0b00101, 0b00110, 0b00101, 0b01110, 0b00100, 0b00000};
    byte connection[8] = {0b00000, 0b01110, 0b10001, 0b00100, 0b01010, 0b00000, 0b00100, 0b00000};
    byte viair[8] = {0b00000, 0b11110, 0b00010, 0b11111, 0b11111, 0b11111, 0b01010, 0b00000};
    byte heat[8] = {0b01111, 0b10000, 0b01110, 0b00001, 0b01110, 0b10000, 0b01111, 0b00000};
    byte cros[8] = {0b10001, 0b11111, 0b10101, 0b00100, 0b10101, 0b11111, 0b10001, 0b00000};

    byte p =4; // liczba pomiarów do uśrednienia
    byte i = 0; // liczba linii pomiaru (4 czujniki+ butla + temp wyspy + ew.ciśn.oleju)
    const byte srednia = 8; // liczba powtórzeń do wyliczenia średniej z pomiarów
    const byte filtr = 4; // filtr cyfrowy dolnoprzepustowy
    const int offset = 3000; // liczba milisek opóźnienia od momentu zmiany trybu pracy sterownika, domyślnie 3000
    int timeAdjust = 0; // liczba milisek estymowana potrzebna na dopasowanie ciśnienia wg aktualnego gapu do targetu
    const byte barup = 150; // empirycznie wyliczony czas (ms) podnoszenia ciśnienia o 1 BAR (zliczyć czas podnoszenia)
    const byte bardown = 250; // empirycznie wyliczony czas (ms) opuszczania ciśnienia o 1 BAR (policzyć czas opuszczania)
    byte ramka = 0;

    //=========================== JOY config ===========================
    const int Fx_mid=545; const int Fy_mid=532; const int Rx_mid=515; const int Ry_mid=516;
    const int Joy_Sens=15; //próg od którego identyfikowane przesuniecie Joy
    const int Joy_Step=16; //dzielnik Joy, max wychylenie to Joy_Step x2
    const int center_hist=5; //ustawiamy histerezę - tylko po przekroczeniu tej wartości od pozycji centralnej będziemy cokolwiek robić
    #define JoyFs A15 //zdefiniowanie pinów przycisków w joy F - INTERRUPT
    #define JoyRs A12 //zdefiniowanie pinów przycisków w joy R - INTERRUPT
    const int JoyFx = A14; //zdefiniowanie pinów osi x w joy F
    const int JoyFy = A13; //zdefiniowanie pinów osi y w joy F
    const int JoyRx = A11; //zdefiniowanie pinów osi x w joy R
    const int JoyRy = A10; //zdefiniowanie pinów osi y w joy R
    int Fx; int Fy; int Rx; int Ry; //odczytamy wartości napięć dla osi X i Y

    byte BTstatus; // status polaczenia BT
    String BTstringAPP;
    String manual = "0000";
    String zaworykod = "00000000";
    String JoyFkod = "00";
    String JoyRkod = "00";
    String Fzawor = "0000";
    String Rzawor = "0000";
    //=========================== JOY config END========================

    int z[] = {0,0,0,0,0,0,0,0}; // kod wykonywania zaworow z polecenia bluetooth
    const byte s[] = {1,2,3,4,5,7}; // analogowe piny czujników (ciśnienia kół FL, FR, RL, RR, butla, napiecie akumulator), temp jest 1wire więc nie ma pinu analog
    const byte scorr[] = {12,2,11,2,20}; // korekta czujnikow cisnienia
    int tirecorr[] = {0,0,0,0}; // sumuje łączny czas korekt autopoziomowania - diagnostyka szczelności
    byte diff[] = {0,0,0,0}; // rożnica miedzy cisnieniem zadanym a rzeczywistym
    int sval[] = {0,0,0,0,0,0,0}; // wartosc poczatkową z czujników
    int qsval[] = {0,0,0,0,0,0,0}; // szybki odczyt czujnikow
    int spomiar[] = {0,0,0,0,0}; // średnia ciśnienia wg której odbywa sie poziomowanie
    // byte lpomiar = 0; // licznik iloci pomiarów przed wykonaniem poziomowania
    const byte svallcdx[] = {0,13,0,13,5,0,9}; // pozycja cisnienia na lcd - kolumna
    const byte svallcdy[] = {0,0,1,1,1,0,1}; // pozycja cisnienia na lcd - wiersz
    const int bar[] = {999,32,38,43,48,60,0,888}; // nastawy predefiniowanego ciśnienia wyrażone w BAR/10
    const byte upvalves[] = {24,28,32,36}; // piny zaworow upustowych
    const byte downvalves[] = {26,30,34,38}; // piny zaworow zasilających
    const byte crossvalves[] = {50,51,52,53}; // piny zaworow krzyzowych
    const byte buzzer = 22; // pin buzzer
    const byte kompresorpin = 40; // pin kompresora
    const byte grzalkapin = 42; // pin podgrzewania zaworów
    const byte sport = 3; // pin trybu sport
    const byte tour = 4; // pin trybu tour
    const byte gleba = 5; // pin trybu trakcji
    const byte climatronic = 6; // pin napiecia climatronika
    int insignialasttryb;
    byte giro = 0;
    byte sportstatus = 0;
    byte tourstatus = 0;
    byte glebastatus = 0;
    byte wilgotnosc = 0; // status wilgotnosci
    byte temperatura = 0; // status temp
    byte licznik = 0; // sekwencja wyświetlacza LCD
    int DHT11_VCC = 9; // czujnik wilgotnosci pin +
    int DHT11_GND = 10; // czujnik wilgotnosci pin -
    volatile int cross = 0; // status cross
    volatile int kompresor = 0; // status kompresora
    volatile int grzalka = 0; // status grzałki wyspy
    volatile int tryb = 0; // domyślny tryb startowy
    volatile int lasttryb = 0; // domyślny tryb startowy
    unsigned long trybLastChange = millis(); // funkcja zegara dla sprawdzania trybu
    unsigned long lastBT = millis(); // funkcja zegara dla sprawdzania polaczenia BT
    int currentHeight = bar[0];
    const float alfa = 0.6; // wsk wyladzanie, im wiecej tym bardziej wygladza
    //float usrednionaWartosc = 0.0; // wygladzanie

    //======================= temperatura DS18B20 ====================
    #define ONEWIRE_PIN 2 // pin czujnika temperatury
    byte address[8] = {0x28, 0xFF, 0xDA, 0x5F, 0x62, 0x17, 0x4, 0xE0}; // Adres czujnika
    OneWire onewire(ONEWIRE_PIN);
    DS18B20 sensors(&onewire);

    //======================= Wilgotnosc DHT ====================
    #define DHT11_PIN 8 // pin dla DHT11
    DHT dht;

    void setup() { //40ms
    #define DiodePin 13
    pinMode(DiodePin, OUTPUT);



    //analogReference(EXTERNAL); //konfiguracja referencyjnego napięcia
    dht.setup(DHT11_PIN); //setup wilgotnosci
    Serial.begin(19200); //start portu COM
    Serial3.begin(9600); //start COM dla BT
    SPI.begin(); //start komunikacji
    pinMode(JoyFx, INPUT); pinMode(JoyFy, INPUT); pinMode(JoyRx, INPUT); pinMode(JoyRy, INPUT);
    pinMode(JoyFs,INPUT_PULLUP);
    pinMode(JoyRs,INPUT_PULLUP);
    pinMode(kompresorpin, OUTPUT);
    pinMode(grzalkapin, OUTPUT);
    pinMode(sport, INPUT);
    pinMode(tour, INPUT);
    pinMode(gleba, INPUT);
    pinMode(climatronic, INPUT);
    pinMode(buzzer, OUTPUT);
    pinMode(DHT11_VCC, OUTPUT);
    pinMode(DHT11_GND, OUTPUT);
    digitalWrite(kompresorpin, HIGH);
    digitalWrite(grzalkapin, HIGH);
    digitalWrite(buzzer, HIGH);
    pinMode(DHT11_VCC, HIGH);
    pinMode(DHT11_GND, LOW);

    //fix dla nieużywanych pinów analogowych by nie robiły zakłóceń
    pinMode(A8, OUTPUT); digitalWrite(A8, LOW);
    pinMode(A9, OUTPUT); digitalWrite(A9, LOW);

    //config pinów zaworów
    for( i = 0; i < 4; i++){
    pinMode(upvalves[i], OUTPUT); digitalWrite(upvalves[i], HIGH);
    pinMode(downvalves[i], OUTPUT); digitalWrite(downvalves[i], HIGH);
    pinMode(crossvalves[i], OUTPUT); digitalWrite(downvalves[i], LOW);
    }

    //config pinów czujników
    //for( i = 0; i < 5; i++){ pinMode(s[i], INPUT_PULLUP); }
    //for( i = 0; i <= 5; i++){ pinMode(s[i], INPUT); }
    pinMode(A1, INPUT_PULLUP);
    pinMode(A2, INPUT_PULLUP);
    pinMode(A3, INPUT_PULLUP);
    pinMode(A4, INPUT_PULLUP);
    pinMode(A5, INPUT_PULLUP);

    //======================= temperatura DS18B20 ====================
    sensors.begin(9);
    sensors.request(address);


    Wire.begin();
    Wire.beginTransmission(0x3F);
    if (Wire.endTransmission() !=0) {}

    lcd.begin(16, 2); // Wybór rodzaju wyświetlacza - 16x2
    lcd.init(); // Start LCD
    lcd.backlight(); // Lights ON
    lcd.createChar(0, znakdol);
    lcd.createChar(1, znakgora);
    lcd.createChar(2, celcius);
    lcd.createChar(3, bticon);
    lcd.createChar(4, connection);
    lcd.createChar(5, viair);
    lcd.createChar(6, heat);
    lcd.createChar(7, cros);
    lcd.home ();
    lcd.print(" Start "); //LCD start up
    tone(buzzer, 1000, 100);delay(100);
    tone(buzzer, 2000, 100);delay(100);
    tone(buzzer, 4000, 100);delay(100);
    tone(buzzer, 6000, 100);delay(500);
    lcd.clear();
    Serial.print("go");

    ReadSensors(); //kolejność autostart
    ShowLCDtryb();
    //akcja.attach(0,500, ReadSensors); // odczyt sensorów ciśnienia
    akcja.attach(0,500, ReadTempWyspaSensors); // odczyt temp
    akcja.attach(1,2500, checkAir); // spr czy potrzeba poziomowania
    akcja.attach(2,50, checkBT); // odczyt BT
    akcja.attach(3,90, trybManual); // manual
    akcja.attach(4,2000, sekwencjaLCD); // status sekwencji lcd
    akcja.attach(5,300, ShowLCDtryb); // zrzut trybu na lcd
    akcja.attach(6,110, JoyTrybChange); // sprawdza stan klawisza UP - tryb 150
    akcja.attach(7,60, sterownikGiroBT); //
    }
  • #24
    khoam
    Level 40  
    ICEMANIK wrote:
    dobrze, wstawiłęm rozmiar "int size = 8192" dla Mega, wtedy wynik to 6694, gdybym zostawił 2048, wtedy wynik to 2047.


    Nie rozumiem, o co chodzi z tym "int size = 8192". W kodzie powinieneś po prostu wstawić:
    Code: c
    Log in, to see the code

    albo:
    Code: c
    Log in, to see the code


    To powinno działać niezależnie od tego, czy płytka jest Uno czy Mega.

    Dodano po 11 [minuty]:

    ICEMANIK wrote:
    zmienne + setup


    A co to jest poniżej? Jakiej biblioteki używasz dla DS18B20?
    Code: c
    Log in, to see the code


    Niezależnie od tego, "request" powinien być w loop() przed każdym kolejnym pomiarem temperatury, a nie tylko raz w setup().
  • #25
    ICEMANIK
    Level 10  
    khoam wrote:
    lcd.print(getFreeMemory());

    Wynik to 6818

    khoam wrote:
    Nie rozumiem, o co chodzi z tym "int size = 8192"

    znalazłem coś takiego, myślałem, że trzeba zmienić w funkcji availableMemory :) :
    Spoiler:
    // this function will return the number of bytes currently free in RAM
    // written by David A. Mellis
    // based on code by Rob Faludi http://www.faludi.com
    int availableMemory() {
    int size = 1024; // Use 2048 with ATmega328
    byte *buf;
    while ((buf = (byte *) malloc(--size)) == NULL);
    free(buf);
    return size;
    }
  • #26
    ICEMANIK
    Level 10  
    Kurcze, niezauważyłem że edytowałeś posta z kolejnymi pytaniami :)

    khoam wrote:
    Jakiej biblioteki używasz dla DS18B20?

    DS18B2..zip Download (67.19 kB)

    pomiar wykonywany jest następująco:
    Spoiler:
    // odczyt z czujnika temperatury wyspy
    void ReadTempWyspaSensors(){
    if (sensors.available()) {
    if (sensors.readTemperature(address)<-100) {sval[6] = 99;}
    else {sval[6] = sensors.readTemperature(address); }
    sensors.request(address);
    }
    ShowLCDsensor();
    }
  • #27
    khoam
    Level 40  
    ICEMANIK wrote:
    pomiar wykonywany jest następująco:


    Pierwszy raz widzę, że ktoś używa takiej biblioteki dla DS18B20, ale pewnie wszystko jeszcze przede mną ;) Muszę się temu na spokojnie przyjrzeć.
  • #28
    ICEMANIK
    Level 10  
    To jest biblioteka chyba z akademii nettigo
  • #29
    arkady_pl
    Level 24  
    khoam wrote:
    arkady_pl wrote:
    Biblioteki potrafią się zakócać. Ja dzisiaj odkryłem, że u mnie biblioteka od wyświetacza OLED na SSD1306 na i2C kłóci się z bibioteką LiquidCrystal_I2C i nie mogę spiąc obu ekranów razem.


    A sprawdzałeś faktyczne adresy i2c za pomocą skanera?

    Brakowało pamięci RAM. Kompilator pokazywał około 1,2k wolnego ale jak podliczyłem dynamiczne zmienne to mi wyszło, że może brakować kilka bajtów. Po pewnych zmianach w kodzie ruszyło z błedem na OLED ale jak przeniosłem co się dało do Flash to działają oba.
  • #30
    khoam
    Level 40  
    arkady_pl wrote:
    Brakowało pamięci RAM. Kompilator pokazywał około 1,2k wolnego ale jak podliczyłem dynamiczne zmienne to mi wyszło, że może brakować kilka bajtów.


    Korzystałeś może z biblioteki Adafruit? Staram się unikać bibliotek z tej stajni - w ogóle nie są one optymalizowane pod kątem zajętości sterty w SRAM.