Please note: Friday June 18 is a holiday celebrating Juneteenth, please allow extra time for your order to arrive and plan accordingly.
0

internal storage how to write/read other data
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

internal storage how to write/read other data

by sekramer10 on Sat Mar 27, 2021 10:23 pm

I am capturing data with sensors and wish to write it and retrieve it from internal storage. I see the example for character strings, but I need to save data that has various sizes, specifically large 1D arrays of ints and unsigned longs. I have read the lfs library but need help as how to work with other variable types and sizes, or can you suggest reference or examples? I am using Arduino code with CPEBF.

sekramer10
 
Posts: 174
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

by adafruit_support_mike on Tue Mar 30, 2021 12:27 am

You have to abuse the type system and use memcpy().

Create a data structure with all the variables you want in it, then create a byte array sizeof(structure) bytes long. Then memcpy() the data structure into the byte array to flatten the data so it can be written to storage, and memcpy() bytes read from storage into the data structure to inflate them into typed data.

adafruit_support_mike
 
Posts: 62799
Joined: Thu Feb 11, 2010 2:51 pm

Re: internal storage how to write/read other data

by sekramer10 on Tue Mar 30, 2021 12:36 am

Thanks, is this a limitation of the flash_nrf5x library, or the chip? Or could a library be written to improve this?

sekramer10
 
Posts: 174
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

by adafruit_support_mike on Tue Mar 30, 2021 10:09 pm

If anything, it's a limitation of when the data is available.

Strictly speaking, declaring a variable of some type means you're not allowed to know how it's represented at the hardware/signal level.. that's the whole point of type systems. The compiler's code generator handles all the work of translating between typed data in the code and binary representations in the hardware, and making sure those representations only get handled by code that will manipulate them in a type-safe way.

The compiler's type system and code generators can only work on data available at compile time though. They never see data that's collected while the compiled binary is running.

All you can do is give the compiler and type system a variable-sized hole that can be filled with bits while the code is running. Stuffing that hole with bits or pulling bits from it is an explicit violation of any type system.

C's type system includes union data structures, which are officially a way to save space when you need to handle collections of data that can have multiple types. You can define a union as a typed value and a byte array of the same size, then use that to convert types to bit patterns, but it's still an abuse of the type system. Using memcpy() does the same thing, but is faster and a bit safer.

adafruit_support_mike
 
Posts: 62799
Joined: Thu Feb 11, 2010 2:51 pm

Re: internal storage how to write/read other data

by sekramer10 on Thu Apr 15, 2021 10:04 pm

I've been working on this for a while, I was wondering if you could give me some assistance with this runtime error error which is:

Code: Select all | TOGGLE FULL SIZE
assertion "block < lfs->cfg->block_count" failed: file "C:\Users\perigalacticon\AppData\Local\arduino15\packages\adafruit\hardware\nrf52\0.21.0\libraries\Adafruit_LittleFS\src\littlefs\lfs.c", line 18, function: lfs_cache_read
Here is the function I'm developing to write data to the internal storage:

Code: Select all | TOGGLE FULL SIZE
const int points = 10;
int current[points] = {800, 100, 200, 300, 400, 500, 600, 700, 800, 900};

void WriteFiles()
{

  Serial.println("measurement done, writing data");
  if ( file.open(FILENAME_CURRENT, FILE_O_WRITE) )
  {
    Serial.println("OK");
    uint8_t *ptr = (uint8_t*)current; 
    for (uint8_t byteCounter = 0; byteCounter < sizeof current; byteCounter++) // byteCounter number of 8-bit bytes in the array.
    {
      // for each byte in current[],
      // write the byte to the file.

      Serial.print("byteCounter ");
      Serial.print(byteCounter);     
      Serial.print("\t");     
      Serial.print("ptr ");
      Serial.print((long)ptr); 
      Serial.print("\t");     
      Serial.print("*ptr ");
      Serial.print((long)*ptr);

      file.write(ptr + byteCounter, 1); //  increment pointer variable each time.
    }

    file.close();

  } else
  {
    Serial.println("data file failed!");
  }
It compiles but I get the above error on the serial monitor after the write command:

Code: Select all | TOGGLE FULL SIZE
22:07:29.991 -> OK
22:07:29.991 -> byteCounter 0   ptr 536895492   *ptr 32assertion "block < lfs->cfg->block_count" failed: file "C:\Users\perigalacticon\AppData\Local\arduino15\packages\adafruit\hardware\nrf52\0.21.0\libraries\Adafruit_LittleFS\src\littlefs\lfs.c", line 18, function: lfs_cache_read

sekramer10
 
Posts: 174
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

by sekramer10 on Sat Apr 17, 2021 10:06 pm

Could you provide some references or examples for working with file read/write operations with the CPXBF filesystem that go beyond storing text? I am pretty stuck at the moment, I'd like to work with 1D arrays of 4-byte ints. In case you're able to help this is my latest simplified sketch that's not working as I expected, just trying to store and read a single byte:

Code: Select all | TOGGLE FULL SIZE
#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>

using namespace Adafruit_LittleFS_Namespace;

File file(InternalFS);

void setup(void)
{
  Serial.begin(115200);
  delay(2000);
  Serial.println("b4 begin");
  InternalFS.begin();
  delay(2000);

  uint8_t current = 100;
  uint8_t *currentPtr = &current;
 
  Serial.println("Writing File:");
  if ( file.open("current.txt", FILE_O_WRITE) )
  {
    Serial.println("file opened");
    file.write(currentPtr, 1);
    file.close();
  } else
  {
    Serial.println("data file failed!");
  }

  delay(2000);

  Serial.println("Reading File:");
  file.open("current.txt", FILE_O_READ);
  if ( file )
  {
    Serial.println("current.txt file exists");
    uint32_t readlen;
    uint8_t * buffer;
    readlen = file.read(buffer, 1);
    Serial.print("readlen ");
    Serial.println(readlen);
    Serial.print("buffer ");
    Serial.println(*buffer);
    file.close();
    Serial.println("endsetup");
  }else
  {
    Serial.println("current.txt " "file does not exist");
  }
}

Serial monitor output is:
Code: Select all | TOGGLE FULL SIZE
21:50:45.558 -> Writing File:
21:50:45.558 -> file opened
21:50:47.562 -> Reading File:
21:50:47.562 -> current.txt file exists
21:50:47.562 -> readlen 1
21:50:47.562 -> buffer 0
21:50:47.562 -> endsetup

sekramer10
 
Posts: 174
Joined: Wed Oct 28, 2015 12:42 am

Please be positive and constructive with your questions and comments.