Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

writing block-wise in sd from an array type struct #33

Closed
Sebastiangka opened this issue Feb 10, 2020 · 6 comments
Closed

writing block-wise in sd from an array type struct #33

Sebastiangka opened this issue Feb 10, 2020 · 6 comments

Comments

@Sebastiangka
Copy link

Sebastiangka commented Feb 10, 2020

Hardware:

Board: NodeMCU-32S
IDE name: Sloeber
Flash Frequency: 40Mhz
Upload Speed: 115200
Computer OS: Windows 10

Description:

Hi Mr. Greiman,
I'm using the Beta Version to save data from a sensor into an sd card. I defined an array type "sample", which is a structure with 32 Byte size. Since my µC only has 600µs to write in between I decided to write in 1024 Byte-Blocks, perhaps my array´s size 4096 Bytes is. After running the program and checking the sd, I saw completely different values than I expected so I'm doing something wrong and I suppose it´s my approach with the buffer pointer.
I thought about casting my values as a string but this takes to long.
Which is the popper way to approach in my case?
Thank you very much.
Sebastian

@greiman
Copy link
Owner

greiman commented Feb 10, 2020

I can't help you write apps, too many people ask.

If you find a bug, isolate the bug in your app and post a simple example that demonstrates the bug.

@Sebastiangka
Copy link
Author

Sebastiangka commented Feb 10, 2020

In the picture bellow you can see what it comes out after running the example program bench with some modifications.
image
here is the code i added to represent in a simple way my case.

.
.
.
struct sample{
  float x; float y;
  };
sample lino[BUF_SIZE];
sample* pl = lino;
.
.
.
  // fill buf with known data
  if (BUF_SIZE > 1) {
    for (size_t i = 0; i < (BUF_SIZE - 2); i++) {
      buf[i] = 'A' + (i % 26);
      pl[i].x = esp_random();
      Serial.print(pl[i].x);
      Serial.print('\t');
      pl[i].y = esp_random();
      Serial.println(pl[i].y);
    }
    buf[BUF_SIZE-2] = '\r';
    pl[BUF_SIZE-2].x = 0.0;
    pl[BUF_SIZE-2].y = 0.0;
  }
  buf[BUF_SIZE-1] = '\n';
  pl[BUF_SIZE-1].x = 0.0;
  pl[BUF_SIZE-1].y = 0.0;
.
.
.
      if (file.write(pl, BUF_SIZE) != BUF_SIZE) {
        error("write failed");
      }
.
.
.

The size from the bench file is correct:
image

I would like to know if there is a special reason why you define buf as a uint_8 pointer and cast buffer32 into an uint8_t? And which would be the consecuences in the spi performance if i defined as an struct

@Sebastiangka
Copy link
Author

I toked a look at the FatFile write function, then I had to inform my self about "reinterpret_cast conversion" and so far as I understand it works only for integers and pointers. As you defined in write-function, buf is void* pointer type and it will be casted direct at the beginning.

const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);

I would like to know how to work with different variables types like float and struct, in order to write them in the Sd-Card. Or if its actually possible to work with them.
Thanks for your time

@greiman
Copy link
Owner

greiman commented Feb 11, 2020

if (file.write(pl, BUF_SIZE) != BUF_SIZE) {
        error("write failed");
      }

The size of pl is not BUF_SIZE bytes. It is sizeof(pl) so you are only writing a portion of the array.

Casting a variable will not result in a text file.

I cast a uint32_t to uint8_t in the bench example since some processors require DMA writes to be aligned on 4-byte boundaries for maximum speed. The Teensy 4 board can write at 22 MB/sec with it's fast 4-bit wide SDHC controller.

Since my µC only has 600µs to write

This rate can't be achieved with a simple program. SD cards can have write latency times of many milliseconds so you must acquire and buffer data to write at this speed. This may require data acquisition in an interrupt routine or a RTOS.

It may not be possible with your board since it is slow for SPI writes.

@Sebastiangka
Copy link
Author

Sebastiangka commented Feb 11, 2020

This may require data acquisition in an interrupt routine or a RTOS.>

That´s my plan. I use a time interrupt to check the values from my sensor, this happen every 1ms and it´s needs ~350µs to read the values. So every 1ms it will be a new sample to my array, is the array full then should be copied in the Sd.

I would be satisfied if I get at least the right values in the Sd, then i would work on the timing problem.

@greiman
Copy link
Owner

greiman commented Feb 11, 2020

You must fix your bugs. You are not writing the correct amount of data to the SD. The data is written as binary, not text.

I am closing this since I don't have time to tutor C++ programming.

@greiman greiman closed this as completed Feb 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants