logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Optymalizacja kodu Arduino dla czujników I2C i zapis na SD

RozgrzanyAndrzej 10 Lip 2018 22:52 1122 19
REKLAMA
  • #1 17322426
    RozgrzanyAndrzej
    Poziom 5  
    Posty: 52
    Ocena: 3
    Witam serdecznie.

    Próbuję napisać kod, który zbiera informację z kilku czujników po magistrali I2C , a następnie zapisywać informacje na karcie SD. Niestety, mój kod jest na tyle słaby i źle napisany że nie mieści mi się na Arduino. Domyślam się, że to kwestia zarezerwowanej i nie zwolnionej pamięci...

    W projekcie używam:
    - Czujnik ciśnienia - MS5837 ( zwraca ciśnienie atmosferyczne, temperaturę oraz głębokość ).
    - Zegarek DS1307 .
    - IMU od Adafruit - LSM9DS1(zwraca dane z żyro w 3 osiach, magnetometru w 3 osiach oraz akcelerometru, także w 3 osiach).
    - Czujnik wilgotności DHT11( korzystam jedynie z czujnika wilgotności).

    Jak zwykle proszę Was o wskazówki i podrzucenie jakiś rozwiązań. Kod podrzucam poniżej.

    Pozdrawiam RA.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 17322561
    Konto nie istnieje
    Konto nie istnieje  
  • #3 17322600
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    RozgrzanyAndrzej napisał:

    [syntax=c] // Data i czas z momentu kompilacji
    clock.setDateTime(__DATE__, __TIME__);
    [syntax]


    Skąd wy wszyscy to kopiujecie?

    Na stringach by można zrobić oszczędności, ale to jest mikro-optymalizacja. Zgadzam się, że za słaby procesor
  • #4 17322643
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Wyrzuć cała funkcje SerialPort i zobaczysz ile pakiecie odzyskasz. O ile rozmiar hex przekracza dopuszczalna pamięć ? Jakie arduino ?

    Pozdr
    Slawek

    Dodano po 1 [minuty]:

    JacekCz napisał:
    RozgrzanyAndrzej napisał:

    [syntax=c] // Data i czas z momentu kompilacji
    clock.setDateTime(__DATE__, __TIME__);
    [syntax]


    Skąd wy wszyscy to kopiujecie?

    Z example biblioteki.
  • #5 17322719
    RozgrzanyAndrzej
    Poziom 5  
    Posty: 52
    Ocena: 3
    nowyARM napisał:
    RozgrzanyAndrzej napisał:
    że nie mieści mi się na Arduino. Domyślam się, że to kwestia zarezerwowanej i nie zwolnionej pamięci

    Mikrokontroler to nie PC. Pamięci flash nie da się zwolnić.

    RozgrzanyAndrzej napisał:
    zapisywać informacje na karcie SD

    FAT pochłania sporo zasobów.
    Zmień uC na większy.


    Wgrywałem na to samo Arduino sketch od MultiWii , który jest kilka rzędy wielkości bardziej obszerny od mojego a zajmuje jedynie 50% pamięci kontrolera.

    Masz na myśli o kondensator na module SD?

    JacekCz napisał:
    RozgrzanyAndrzej napisał:

    [syntax=c] // Data i czas z momentu kompilacji
    clock.setDateTime(__DATE__, __TIME__);
    [syntax]


    Skąd wy wszyscy to kopiujecie?

    Na stringach by można zrobić oszczędności, ale to jest mikro-optymalizacja. Zgadzam się, że za słaby procesor


    Z biblioteki układu. Tak jak pisałem wyżej - inne większe i lepiej napisane programy kompilują się bez problemu.

    rs6000 napisał:
    Wyrzuć cała funkcje SerialPort i zobaczysz ile pakiecie odzyskasz. O ile rozmiar hex przekracza dopuszczalna pamięć ? Jakie arduino ?

    Pozdr
    Slawek

    Dodano po 1 [minuty]:

    JacekCz napisał:
    RozgrzanyAndrzej napisał:

    [syntax=c] // Data i czas z momentu kompilacji
    clock.setDateTime(__DATE__, __TIME__);
    [syntax]


    Skąd wy wszyscy to kopiujecie?

    Z example biblioteki.


    Serial to jakieś 30% całości. W tym momencie program jest za duży o jakieś 7% (~300 bajtów). Do tego celu używam kona arduino Blue pro micro ( odczytywane przez kompilator jako leonardo ). Problem w tym, że to nie koniec rozbudowy programy, a jedynie początek. Musze dodać jeszcze 4 urządzenia na i2c oraz SoftwareSerial.
  • Pomocny post
    #6 17322757
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    No to masz odpowiedż, musisz zmienic uC a nie optymalizowac kod.

    Pozdr
    Slawek
  • REKLAMA
  • #7 17322784
    Konto nie istnieje
    Konto nie istnieje  
  • #8 17322822
    RozgrzanyAndrzej
    Poziom 5  
    Posty: 52
    Ocena: 3
    nowyARM napisał:
    RozgrzanyAndrzej napisał:
    W tym momencie program jest za duży o jakieś 7%

    Raczej o 70%. Nigdzie nie widzę abyś sprawdzał czy operacja powiodła się (np otwarcie pliku na karcie SD), nie sprawdzasz więc i nie dajesz komunikatów błędu. Nie używasz watchdoga. Masz jakieś dziwne delay. Gdy LSM9DS1 nie działa po prostu zawieszasz się, zamiast zrobić kilka prób połączenia. TWI w AVR lubi zawiesić się na statusie 0xF8, nie obsługujesz tego. I2C może zostać zablokowana przez slave. Trzeba napisać funkcję, która odłączy TWI, wygeneruje 9 impulsów na SCK, podłączy TWI i spróbuje ponownej komunikacji. W czasie pracy programu odłącz RTC. Jaki efekt?

    To co pokazałeś, to dopiero początek programu. Programu nieodpornego praktycznie na jakiekolwiek błędy.


    Okej, ale dlaczego kod który jest znacznie większy zajmuje połowę pamięci programu, a mój nie może się nawet wgrać?
  • #9 17322861
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #10 17324322
    trol.six
    Poziom 31  
    Posty: 1650
    Pomógł: 151
    Ocena: 381
    RozgrzanyAndrzej napisał:
    Serial to jakieś 30% całości. W tym momencie program jest za duży o jakieś 7% (~300 bajtów). Do tego celu używam kona arduino Blue pro micro ( odczytywane przez kompilator jako leonardo ). Problem w tym, że to nie koniec rozbudowy programy, a jedynie początek

    Czyli wstępnie, jak już nadmieniono, sprzęt za słaby do zadania. Ale możesz się pobawić np tak:

    Możesz zrezygnować z osobnych funkcji SerialPort i sd,
    wywołanie ich też może zajmować bajty, i widze że dane zapisywane są tak samo.

    Zmienne tekstowe umieść we flash:
    http://playground.arduino.cc/Main/PROGMEM

    Nagłówek:
    Cytat:
    #include <avr/pgmspace.h>


    Dla przykładu tabelka z datą. Więc to wklejasz jako swoje dane:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    A w petli loop zamiast funkcji umieszczasz obsługe odczytującą kolejne dane.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Coś w tym stylu. Tak samo dla obsługi innych danych.
    Tam gdzie masz Serial.println(" gauss") powinno zadziałać " gauss\n"

    \n to jest znak nowej linii
    czasem trzeba użyć " gauss\r\n"
    \r wraca na początek linii
  • Pomocny post
    #11 17324573
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #12 17325290
    trol.six
    Poziom 31  
    Posty: 1650
    Pomógł: 151
    Ocena: 381
    nowyARM napisał:
    Tylko po co? Gdyby była to ostateczna wersja softu to ok ale

    Skoro kod będzie się rozrastał, może i jest sens pisać w miarę oszczędnie niż pisać dwa razy. Szczególnie że można zastosować metodę copiego-pasta. Myśle że autor tematu sam podejmie decyzje. Nie zawsze jest taka możliwość stablicowania danych.
    Nawet przeróbka na inną architekturę nie powinna stanowić problemu, chociaż PROGMEM i pgm_read_word to typowo na avr jest.
  • REKLAMA
  • #13 17325383
    Konto nie istnieje
    Konto nie istnieje  
  • #14 17325959
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    Dyskusja jak zwykle robi się nie na temat. Atmega328 z Arduino ma 2 kB SRAM, co jest aż nadto dla realizacji zadania autora. Problem z pamięcią związany jest z g++, który umieszcza VMT klas w SRAM, w efekcie pamięci tej zaczyna szybko ubywać, szczególnie jeśli używane są hurtowo metody wirtualne i dziedziczenie.
    Niemniej, sensownie napisany program, spokojnie się w tym procku zmieści. Odczyt I2C i zapis na SD to nie rocket science. Zapewne Arduino jakoś implementuje FATFS, warto się temu przyjrzeć, bo ten moduł można skonfigurować na różne sposoby. Potrzebuje on w zależności od opcji z jakimi jest skompilowany 4-8 kB FLASH i silkaset do ciut ponad 1 kB SRAM. Po okrojeniu działa to nawet na ATTiny. Dla tak prostych zadań pytanie czy w ogóle jest sens korzystać z Arduino, czy nie prościej ściągnąć FATFS, dodać obsługę I2C (kilkanaście linii kodu) i sprawa załatwiona.
  • #15 17326513
    Konto nie istnieje
    Konto nie istnieje  
  • #16 17332041
    RozgrzanyAndrzej
    Poziom 5  
    Posty: 52
    Ocena: 3
    Okej, to może po kolei.

    @nowyARM
    To nie jest kwestia różnicy w cenie, a zwłaszcza takiego rzędu. Miałem pomysł na zrobienie tego na Arduino, bo z tym środowiskiem najzwyczajniej pracowałem do tej pory.

    @trol.six Dziękuję za kawałek kodu. Własnie o podobne wskazówki mi chodziło, by następnym razem nie mieć tego problemu i pisać kod coraz bardziej wydajnie.

    Myślę nad tym, zeby dla każdej funkcji zrobić oddzielną płytkę z mikro-kontrolerem (np. oddzielna do obsługi i2c, zapisu na SD, obsługi LEDów oświetleniowych itp ), a wszystkie podłączyć właśnie do jakiegoś arduino MEGA. Czy to dobry kierunek ?

    Wracając do mojego "nieefektywnego " kodowania, to każda wskazówka jest mile widziana .

    Pozdrawiam, RA.
  • #17 17332094
    Konto nie istnieje
    Konto nie istnieje  
  • #18 17332143
    RozgrzanyAndrzej
    Poziom 5  
    Posty: 52
    Ocena: 3
    @nowyARM Nigdy nie pracowałem na ARM. Z tego co wiem - na ARM nie ma tylu bibliotek , a moje kodowanie w głównej mierze się na nich opiera.

    Tak, chodziło mi o to, że wyświetlam/zapisuje jedynie wilgotność, bo samą temperaturę otrzymuje z bardziej dokładnego czujnika w module pomiaru ciśnienia <- https://bluerobotics.com/store/electronics/bar30-sensor-r1/
  • #19 17332163
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    RozgrzanyAndrzej napisał:
    Nigdy nie pracowałem na ARM. Z tego co wiem - na ARM nie ma tylu bibliotek , a moje kodowanie w głównej mierze się na nich opiera.


    A masz jakieś zdanie w/s jakości bibliotek Arduino/AVR?
    Olbrzymia większość twórców testowała to w swoim stabilnym środowisku, NIGDY nie analizując "co by było gdyby obok była inna" *)
    Wielokrotnie je oglądałem, w wielu autor zdradza wyraźnie nieznajomość C++


    *) testowanie w intencji "udowodnić że działa" jest bez sensu.
  • Pomocny post
    #20 17332164
    Konto nie istnieje
    Konto nie istnieje  

Podsumowanie tematu

✨ Użytkownik zmaga się z problemem optymalizacji kodu Arduino, który zbiera dane z czujników I2C i zapisuje je na karcie SD. W projekcie wykorzystuje czujniki MS5837, DS1307, LSM9DS1 oraz DHT11. Wiele odpowiedzi sugeruje, że problemem jest zbyt mała pamięć mikrokontrolera (ATmega328), co prowadzi do trudności w kompilacji kodu. Użytkownicy zalecają rozważenie użycia większego mikrokontrolera, takiego jak Arduino Mega lub ARM, oraz optymalizację kodu poprzez usunięcie niepotrzebnych funkcji, takich jak SerialPort, oraz przeniesienie zmiennych tekstowych do pamięci flash (PROGMEM). Dodatkowo, podkreślono znaczenie obsługi błędów w komunikacji I2C oraz zapisu na SD.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA