Funkcja zapisu/odczytu do/z FRAM

iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

Proszę o pomoc w poprawnym napisaniu dwóch funkcji, które wymieniają informacje z FRAM.
Widzę, na czym polegają błędy, ale nie umiem sobie z nimi poradzić.

1. Zapis do FRAM

memcpy(tKpop11, (void *)&nTemp24Max_Val, 4);
i2cFRAM.write(Temp24Max_Offset, tKpop11, 4);

powyższych dwóch linii używam wielokrotnie, zmieniając parametry, tu przykładowe nazwy:
- tKpop1 - tablica 4 bajtowa na zapisywaną wartość
- &nTemp24Max_Val - adres zapisywanej zmiennej
- Temp24Max_Offset - adres FRAM, int

2. Odczyt z FRAM

i2cFRAM.read(CurrentDay_Offset, tcDay, 4);
memcpy((void *)&nCurrentDay, tcDay, 4);

- CurrentDay_Offset - adres zmiennej we FRAM
- tcDay - tablica na wartość zmiennej
- &nCurrentDay - adres zmiennej

Używam tych operacji wielokrotnie dla różnych zmiennych i chciałbym wykorzystywać do tego dwie funkcje np. FRAM_read i FRAM_write
Wywołanie byłoby z parametrami, np:

FRAM_write (nazwa_zmiennej, adres_FRAM, tablica_zmiennej)
FRAM_read (adres_FRAM, tablica_zmiennej, nazwa_zmiennej)

Póki co, próbowałem napisać tak:

Code: Select all

      void FRAM_Write(int tTabl, const int VarValue, int FRAM_address)
      {
        memcpy(tTabl, (void *)&VarValue, 4);
        i2cFRAM.write(FRAM_address, tTabl, 4);
      }
i mam błędy:

1. przy "tTabl":
argument of type "int" is incompatible with parameter of type "void *"
int tTabl
==============
2. przy i2cFRAM.write:
no instance of overloaded function "Adafruit_EEPROM_I2C::write" matches the argument list
WI-240908-2130.ino(1058, 17): argument types are: (int, int, int)
WI-240908-2130.ino(1058, 17): object type is: Adafruit_EEPROM_I2C
write
+2 overloads
Writes a byte at the specific EEPROM address
Parameters:
addr – The 16-bit address to write to in EEPROM memory
value – The 8-bit value to write at addr
==================

EDIT: 15:40
Udało mi się usunąć błąd w pierwszej linii:

Code: Select all

obecnie: memcpy((void *)&tTabl, (void *)&VarValue, 4);
było:    memcpy(tTabl, (void *)&VarValue, 4);
Już się nie czepia niedopasowania typu danych.

Drugi błąd pozostał ;-(
iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

Problem jest w drugiej linii, pierwsza nie zgłasza błedu.

To działa: (nazwa bufora danych podana jest jako nazwa "tkpop11")

Code: Select all

      void FRAM_WriteOK( char &tTabl, const int VarValue, int FRAM_address)
      {
        memcpy(tKpop11, (void *)&nTemp24Max_Val, 4);
        i2cFRAM.write(Temp24Max_Offset, tKpop11, 4);
      }
A to nie działa: (różnica: próbuję podać nazwę/ adres bufora z danymi jako argument funkcji)

Code: Select all

      void FRAM_Write( char &tTabl, const int VarValue, int FRAM_address)
      {
        memcpy((void *)&tTabl, (void *)&VarValue, 4);
        i2cFRAM.write(FRAM_address, *tTabl, 4);
      }
nie potrafię przekazać jako argumentu funkcji tablicy, w której są przechowywane wartości do kopiowania.
Ta tablica "tKpop11" jest definiowana tak:

Code: Select all

uint8_t tKpop11[4];

no i potrzebuję jej nazwę/adres przekazać jako argument funkcji, bo tych tablic/buforów jest np. 12 różnych.
[email protected]
Posts: 1585
Joined: Mon Feb 06, 2023 8:56 am
Has thanked: 18 times
Been thanked: 26 times

Post

iM@rek wrote: Mon Sep 09, 2024 8:56 pm Problem jest w drugiej linii, pierwsza nie zgłasza błedu.

To działa: (nazwa bufora danych podana jest jako nazwa "tkpop11")

Code: Select all

      void FRAM_WriteOK( char &tTabl, const int VarValue, int FRAM_address)
      {
        memcpy(tKpop11, (void *)&nTemp24Max_Val, 4);
        i2cFRAM.write(Temp24Max_Offset, tKpop11, 4);
      }
A to nie działa: (różnica: próbuję podać nazwę/ adres bufora z danymi jako argument funkcji)

Code: Select all

      void FRAM_Write( char &tTabl, const int VarValue, int FRAM_address)
      {
        memcpy((void *)&tTabl, (void *)&VarValue, 4);
        i2cFRAM.write(FRAM_address, *tTabl, 4);
      }
nie potrafię przekazać jako argumentu funkcji tablicy, w której są przechowywane wartości do kopiowania.
Ta tablica "tKpop11" jest definiowana tak:

Code: Select all

uint8_t tKpop11[4];

no i potrzebuję jej nazwę/adres przekazać jako argument funkcji, bo tych tablic/buforów jest np. 12 różnych.
https://letmegooglethat.com/?q=passing+ ... ction+in+c

Poczytaj sobie o typach danych i jak je przekazać do funkcji
iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

[email protected] wrote: Tue Sep 10, 2024 4:40 am
Dzięki za wędkę ;-)
Poczytałem, trochę zrozumiałem i trochę już działa.
[email protected]
Posts: 1585
Joined: Mon Feb 06, 2023 8:56 am
Has thanked: 18 times
Been thanked: 26 times

Post

iM@rek wrote: Tue Sep 10, 2024 12:05 pm
[email protected] wrote: Tue Sep 10, 2024 4:40 am
Dzięki za wędkę ;-)
Poczytałem, trochę zrozumiałem i trochę już działa.
No to super że do przodu 😁
iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

Funkcje działają, wrzucam to, może się komuś przyda:

1. Funkcja zapisu do FRAM:

Code: Select all

    void FRAM_Write(uint8_t tTabl[4], int VarValue, int FRAM_address)
    {
      memcpy(tTabl, (void *)&VarValue, 4);
      i2cFRAM.write(FRAM_address, tTabl, 4);
    }
Przykładowe wywołanie:

Code: Select all

      FRAM_Write(tKpop11, nTemp24Max_Val, Temp24Max_Offset);
Argumenty:
- tKpop11: uint8_t tTabl[4] - tablica 4-ro bajtowa na zapisywaną wartość
- nTemp24Max_Val: int VarValue - zapisywana 4-ro bajtowa (int) wartość
- Temp24Max_Offset: int FRAM_address - adres w pamięci FRAM

2. Funkcja odczytu z FRAM:

Code: Select all

    int FRAM_Read(uint8_t tTabl[4], int VarValue, int FRAM_address)
    {
      i2cFRAM.read(FRAM_address, tTabl, 4); // odczyt z adr FRAM do tabl: [4 bajty])
      memcpy((void *)&VarValue, tTabl, 4);  // kopiuje blok z tTabl do pamięci pod adr zmiennej VarVal, 4b
      return VarValue;
    }
Przykładowe wywołanie:

Code: Select all

nTemp24Max_Val = FRAM_Read(tKpop11, nTemp24Max_Val, Temp24Max_Offset);
Argumenty j.w.
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

W jakim celu przekazujesz to tTab tutaj: FRAM_Write(uint8_t tTabl[4], int VarValue, int FRAM_address) ?

Ogólnie możesz bezpośrednio zapisywać i odczytywać int'a:

Code: Select all

i2cFRAM.write(FRAM_address, &VarValue, sizeof(VarValue));
i analogicznie read.
Najlepsze suple dla Twojego domu :mrgreen:
iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

klew wrote: Wed Sep 11, 2024 11:51 am W jakim celu przekazujesz to tTab tutaj: FRAM_Write(uint8_t tTabl[4], int VarValue, int FRAM_address) ?
Zrobiłem to kiedyś zgodnie z bibliotekami (przykładami|) AdaFruit:
\Adafruit_FRAM_I2C\examples\write_multibyte
Wymiana danych z FRAM odbywa się 2-etapowo:
Zapis:
1. Wartość do tablicy
2. Zawartość (4 elementy) tablicy pod adres FRAM
Odczyt:
1. Wartość z adresu FRAM do tablicy (4 bajty)
2. Zawartość tablicy pod adres zmiennej
Ogólnie możesz bezpośrednio zapisywać i odczytywać int'a:

Code: Select all

i2cFRAM.write(FRAM_address, &VarValue, sizeof(VarValue));
i analogicznie read.
"Sizeof()" - dzięki, użyję.

Niestety, użycie bezpośrednio:

Code: Select all

    void FRAM_Write(uint8_t tTabl[4], int VarValue, int FRAM_address)
    {
      i2cFRAM.write(FRAM_address, &VarValue, sizeof(VarValue));
zgłasza błędy:
no instance of overloaded function "Adafruit_EEPROM_I2C::write" matches the argument list
WI-240911-2200.ino(1243, 15): argument types are: (int, int *, unsigned int)
WI-240911-2200.ino(1243, 15): object type is: Adafruit_EEPROM_I2C
write
+2 overloads
Writes a byte at the specific EEPROM address
Parameters:
addr – The 16-bit address to write to in EEPROM memory
value – The 8-bit value to write at addr
Returns:
True on I2C command success, false on timeout or I2C failure
chyba funkcja oczekuje wskaźnika "int *" ...
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

iM@rek wrote: Thu Sep 12, 2024 6:52 am chyba funkcja oczekuje wskaźnika "int *" ...
On dostał wskaźnik na int i nie wie co zrobić.
Pewnie rzutowanie na void * wystarczy:
i2cFRAM.write(FRAM_address, (void *)&VarValue, sizeof(VarValue));

albo jakiś:
i2cFRAM.write(FRAM_address, reinterpret_cast<void *>(&VarValue), sizeof(VarValue));

A najlepiej sprawdzić jakiego typu zmiennej oczekuje ta metoda. Powinien być tam gdzieś plik .h od tego i2cFRAM
Najlepsze suple dla Twojego domu :mrgreen:
iM@rek
Posts: 376
Joined: Thu Feb 09, 2023 1:25 pm

Post

Dzięki za zainteresowanie.
Działa, zostawiam, póki co nie ruszam.

Return to “Pomoc”