Elektroda.pl
Elektroda.pl
X

Search our partners

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

Optymalizacja kodu z kilkoma czujnikami I2C.

10 Jul 2018 22:52 693 19
  • Level 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.

    Code: c
    Log in, to see the code
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Computer ControlsComputer Controls
  • User removed account  
  • Level 38  
    RozgrzanyAndrzej wrote:

    [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
  • Level 34  
    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 wrote:
    RozgrzanyAndrzej wrote:

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


    Skąd wy wszyscy to kopiujecie?

    Z example biblioteki.
  • Level 3  
    nowyARM wrote:
    RozgrzanyAndrzej wrote:
    ż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 wrote:
    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 wrote:
    RozgrzanyAndrzej wrote:

    [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 wrote:
    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 wrote:
    RozgrzanyAndrzej wrote:

    [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.
  • Helpful post
    Level 34  
  • Computer ControlsComputer Controls
  • User removed account  
  • Level 3  
    nowyARM wrote:
    RozgrzanyAndrzej wrote:
    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ć?
  • User removed account  
  • Helpful post
    Level 31  
    RozgrzanyAndrzej wrote:
    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:
    Quote:
    #include <avr/pgmspace.h>


    Dla przykładu tabelka z datą. Więc to wklejasz jako swoje dane:
    Code: c
    Log in, to see the code

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

    Code: c
    Log in, to see the code

    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
  • Helpful post
    User removed account  
  • Level 31  
    nowyARM wrote:
    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.
  • User removed account  
  • Moderator of Microcontroller designs
    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.
  • User removed account  
  • Level 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.
  • User removed account  
  • Level 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/
  • Level 38  
    RozgrzanyAndrzej wrote:
    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.
  • Helpful post
    User removed account