internal storage how to write/read other data

Play with it! Please tell us which board you're using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
sekramer10
 
Posts: 185
Joined: Wed Oct 28, 2015 12:42 am

internal storage how to write/read other data

Post by sekramer10 »

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.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: internal storage how to write/read other data

Post by adafruit_support_mike »

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.

User avatar
sekramer10
 
Posts: 185
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

Post by sekramer10 »

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

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: internal storage how to write/read other data

Post by adafruit_support_mike »

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.

User avatar
sekramer10
 
Posts: 185
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

Post by sekramer10 »

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

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

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

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

User avatar
sekramer10
 
Posts: 185
Joined: Wed Oct 28, 2015 12:42 am

Re: internal storage how to write/read other data

Post by sekramer10 »

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

#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

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

Locked
Please be positive and constructive with your questions and comments.

Return to “Circuit Playground Classic, Circuit Playground Express, Circuit Playground Bluefruit”