Read data from memory chip W25N01GV

Igor_K

Member
Hi everyone,
Please help with the code. It is necessary to output data from the matrix synchronously with the fronts of incoming pulses. Previously, the code for outputting matrix data through memory PSRAM on Teensy 4.1 was implemented. But the memory is limited to 8+8 = 16 Mbytes. But now I need more. Therefore, I will try to use a soldered flash memory chip W25N01GVZEIG. It is necessary to read the matrix (where the data is stored in bytes to reduce the memory size by 8 times) directly from the flash. These matrices represent only "0" and "1". I have written the code and am doing the check on a small size 2x2 matrix. Filled the matrix file with data in bytes 254 128 and the second line 0 127. Got the result;
"LittleFS Matrix Read Test
Volume size: 125 MByte
File opened successfully. Reading and sending data...
0011001000110101 0011010000100000 0011000100110010 0011100000001101 0000101000110000 0010000000110001 0011001000110111 0000110100001010
Data has been sent successfully."

And it should be:
11111110 10000000 00000000 01111111

What is the problem. Below is my code
Thanks in advance for your community support.

#include <LittleFS.h>
LittleFS_QSPIFlash myfs; // NOR FLASH
LittleFS_QPINAND myfs_NAND; // NAND FLASH 1Gb

const int rows = 2; // 2000
const long cols = 2; // 72000
bool dataSent = false;
void setup() {
pinMode(5, INPUT);
pinMode(8, INPUT);
pinMode(2, OUTPUT);
Serial.begin(9600);
while (!Serial); // wait for Arduino Serial Monitor
Serial.println("LittleFS Matrix Read Test");

if (!myfs_NAND.begin()) {
Serial.println("Error initializing NAND FLASH");
while (1); //
}
Serial.printf("Volume size: %d MByte\n", myfs_NAND.totalSize() / 1048576);
}

void loop() {
if (!dataSent) {
readAndSendData();
dataSent = true;
}
}

void readAndSendData() {
File file = myfs_NAND.open("/mbyte2-2.txt", FILE_READ);
if (!file) {
Serial.println("Error: could not open mbyte2-2.txt");
return;
}
Serial.println("File opened successfully. Reading and sending data...");
while (file.available()) {
if(digitalRead(8)) {
while(digitalRead(8) == 1);
}
while(digitalRead(8) == 0);

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int byteValue = file.read(); // Reading one byte
for (int bitPos = 7; bitPos >= 0; bitPos--) {
int bitValue = (byteValue >> bitPos) & 0x01; // Getting a bit

if(digitalRead(5)) {
while(digitalRead(5) == 1);
}
// The pin is now LOW, wait for it to go HIGH
while(digitalRead(5) == 0);

// Sending a bit through a port
Serial.print(bitValue); // Sending to Serial for Debugging
digitalWrite(2, bitValue);
}
}
Serial.print(" "); // Separator between lines for clarity
// }
break; // End the loop once the data has been sent once
}
}

file.close();
Serial.println("\nData has been sent successfully.");
}
 
What is the problem.

You're not printing a space character after the loop which prints 8 digits. And where you are printing a space character, you probably meant to print a newline, so the data ends up formatted like a matrix rather than 1 huge line.

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int byteValue = file.read(); // Reading one byte
for (int bitPos = 7; bitPos >= 0; bitPos--) {
int bitValue = (byteValue >> bitPos) & 0x01; // Getting a bit

if (digitalRead(5)) {
while (digitalRead(5) == 1);
}
// The pin is now LOW, wait for it to go HIGH
while (digitalRead(5) == 0);

// Sending a bit through a port
Serial.print(bitValue); // Sending to Serial for Debugging
digitalWrite(2, bitValue);
}
// <--- this where you should print the space character so bytes don't run together
}
Serial.print(" "); // Separator between lines for clarity <-- probably should print a newline here
 
Sorry. I put the separator for clarity. The data is not read from the file correctly. int byteValue = file.read(); reads the data incorrectly. Should be 254 128 0 127. Only four numbers. But it turned out

LittleFS Matrix Read Test
Volume size: 125 MByte
File opened successfully. Reading and sending data...
50505050505050505353535353535353 52525252525252523232323232323232 49494949494949495050505050505050 56565656565656561313131313131313 10101010101010104848484848484848 32323232323232324949494949494949 50505050505050505555555555555555 13131313131313131010101010101010
Data has been sent successfully.

For debugging, I disabled the check for the front of the enable pulse and print only the data on the screen after reading.

while (file.available()) {
/* if(digitalRead(8)) {
while(digitalRead(8) == 1);
}
while(digitalRead(8) == 0); // The pin has just gone HIGH (leading edge)
*/
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int byteValue = file.read(); // Reading one byte
for (int bitPos = 7; bitPos >= 0; bitPos--) {
int bitValue = (byteValue >> bitPos) & 0x01; // Getting a bit
/*
if(digitalRead(5)) { // If the pin is already HIGH
while(digitalRead(5) == 1); // wait for it to go lOW
}
// The pin is now LOW, wait for it to go HIGH
while(digitalRead(5) == 0); // The pin has just gone HIGH (leading edge)
*/
// Sending a bit through a port
Serial.print(byteValue);
// Serial.print(bitValue); // Sending to Serial for Debugging
// digitalWrite(2, bitValue);
}
}
Serial.print(" "); // Separator between bytes for clarity
// }
break; // End the loop once the data has been sent once
}
}

file.close();
Serial.println("\nData has been sent successfully.");
 
I am guessing your file is wrong... Also your current test sketch is outputting each character 8 times...
File opened successfully. Reading and sending data...
50505050505050505353535353535353 52525252525252523232323232323232 49494949494949495050505050505050 56565656565656561313131313131313 10101010101010104848484848484848 32323232323232324949494949494949 50505050505050505555555555555555 13131313131313131010101010101010
Data has been sent successfully.
So: if you take the first set of characters you have: 50 53 52 32:
Which as ASCII characters are: '2' '5' '4' space.

So whatever generated this file, maybe did something like: myfile.print(254);
The print statement takes a value and outputs the human readable set of characters that represent the actual value...
whereas: myfile.write(254);
will write one byte with the actual value 254.

Edit: Also please post sketches like this in code tags... that is the </> button toward the upper left of the edit box...
 
To make it easier to understand, I changed the code and display the data from the file on the screen. The file contains only 4 numbers in two lines: 254 128 and 0 127. The program must also read these 4 numbers: 254 128 0 127

This is what actually happens

LittleFS Matrix Read Test
Volume size: 125 MByte
File opened successfully. Reading and sending data...
5053 5232 4950 5613 1048 3249 5055 1310
Data has been sent successfully.


while (file.available()) {
/* if(digitalRead(8)) {
while(digitalRead(8) == 1);
}
while(digitalRead(8) == 0); // The pin has just gone HIGH (leading edge)
*/
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int byteValue = file.read(); // Reading one byte
Serial.print(byteValue);
for (int bitPos = 7; bitPos >= 0; bitPos--) {
int bitValue = (byteValue >> bitPos) & 0x01; // Getting a bit
/*
if(digitalRead(5)) { // If the pin is already HIGH
while(digitalRead(5) == 1); // wait for it to go lOW
}
// The pin is now LOW, wait for it to go HIGH
while(digitalRead(5) == 0); // The pin has just gone HIGH (leading edge)
*/
// Sending a bit through a port
// Serial.print(byteValue);
// Serial.print(bitValue); // Sending to Serial for Debugging
// digitalWrite(2, bitValue);
}
}
Serial.print(" "); // Separator between bytes for clarity
// }
break; // End the loop once the data has been sent once
}
}

file.close();
Serial.println("\nData has been sent successfully.");
}
 
The file contains only 4 numbers in two lines: 254 128 and 0 127. The program must also read these 4 numbers: 254 128 0 127

This is what actually happens

LittleFS Matrix Read Test
Volume size: 125 MByte
File opened successfully. Reading and sending data...
5053 5232 4950 5613 1048 3249 5055 1310
Data has been sent successfully.
As I mentioned in the previous post. Your file does not contain 4 bytes of data, but instead it contains the Ascii representations
of your 4 numbers: Like the code that generated this file did something like:
file output of the string "254 128\r0 127\n\r");

As I mentioned, the first '2' character in ascii has the decimal value of 50 or hex 0x32...

If that is the desired format of the file, your input code needs to read in the bytes and convert to the value to the underlying
number you want:

Which can be something like:
Code:
uint8_t byteValue = 0;
    int char = file.read();
    while ((char >= '0') && (char <= '9')) {
        byteValue = byteValue * 10 + (char - '0');
        char = file.read();
    }
...

You might be able to use something the like parseInt method... Been awhile like: byteValue = file.parseInt()
There are some optional parameters, have not used this in awhile, so unsure if file class allows it, and if we handle the
different optional parameters or not:

Again lot easier to read code, when it is formatted... (Code tags)
 
This is the result.

254 128 0 0 127 0

How to get rid of extra zeros.
Should be
254 128 0 127

Code:
uint8_t byteValue = 0;
int char1 = file.read();
while ((char1 >= '0') && (char1 <= '9')) {
      byteValue = byteValue * 10 + (char1 - '0');
      char1 = file.read();
}
 
You can probably get more people involved in this conversation if you invest just a small amount of extra effort to make running your programs easier for everyone.

First, copy the whole program. It's easy, just Ctrl-A to select all and Ctrl-C to copy in Arduino, then in the code popup on here on the forum, Ctrl-V.

Second, consider that most people with a Teensy handy probably have a SD card connected, but not this specific NAND flash chip. If you used the SD library only, you'll open up the possibility of many more people being able to quickly copy your program into Arduino IDE and able to run it easily on the hardware they have.

Third, if your program first uses very simple code to write known data to the file and close it, then open it and try to read, anyone can just copy the program into Arduino and run it... without having to go through the guesswork and extra steps of trying to create a file with the same data you have.

I know this is extra work for you. Maybe it is unnecessary. Kurt and I already tried to help. Earlier I did copy your program into Arduino and spent a minute modifying it... all because I want to help you. But that is extra work for me, and for everyone else who might try to help you. If you put in just a little extra work to do these 3 things, odds are pretty good you'll get me and others to help more.
 
I have written the code and am doing the check on a small size 2x2 matrix. Filled the matrix file with data in bytes 254 128 and the second line 0 127. Got the result;

“LittleFS Matrix Read Test
Volume size: 125 MByte
File opened successfully. Reading and sending data...
254 128 0 0 127 0
Data has been sent successfully.”

How to get rid of extra zeros.
Should be
254 128 0 127

Code:
#include <LittleFS.h>
LittleFS_QSPIFlash myfs;      // NOR FLASH
LittleFS_QPINAND myfs_NAND;   // NAND FLASH 1Gb

const int rows = 2;      
const long cols = 2;      

bool dataSent = false;

void setup() {
  pinMode(5, INPUT);  
  pinMode(8, INPUT);  
  pinMode(2, OUTPUT);
  Serial.begin(9600);
  while (!Serial); // wait for Arduino Serial Monitor
  Serial.println("LittleFS Matrix Read Test");

 
  if (!myfs_NAND.begin()) {
    Serial.println("Error initializing NAND FLASH");
    while (1);
  }
  Serial.printf("Volume size: %d MByte\n", myfs_NAND.totalSize() / 1048576);
}

void loop() {
  if (!dataSent) {      
    readAndSendData();  
    dataSent = true;    
  }
}

void readAndSendData() {
  File file = myfs_NAND.open("/mbyte2-2.txt", FILE_READ);
  if (!file) {
    Serial.println("Error: could not open mbyte2-2.txt");
    return;
  }
  Serial.println("File opened successfully. Reading and sending data...");
  while (file.available()) {
   /*  if(digitalRead(8)) {          
            while(digitalRead(8) == 1);
       }
       while(digitalRead(8) == 0);  
    */
      for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
        //  int byteValue = file.read();  // Reading one byte
          uint8_t byteValue = 0;
          int char1 = file.read();
            while ((char1 >= '0') && (char1 <= '9')) {
                 byteValue = byteValue * 10 + (char1 - '0');
                 char1 = file.read();
            }
                 
          Serial.print(byteValue);
          Serial.print(" "); // Separator between bytes for clarity
          for (int bitPos = 7; bitPos >= 0; bitPos--) {
            int bitValue = (byteValue >> bitPos) & 0x01;  // Getting a bit
        /*
            if(digitalRead(5)) {             
                      while(digitalRead(5) == 1); 
                  }
                  
                  while(digitalRead(5) == 0);  
           */
            // Sending a bit through a port
         //   Serial.print(byteValue);
          //  Serial.print(bitValue);  // Sending to Serial for Debugging
          //  digitalWrite(2, bitValue);
          }
        }
        Serial.print(" ");  // Separator between bytes for clarity
    //  }
      break;  // End the loop once the data has been sent once
    }
  }

  file.close();
  Serial.println("\nData has been sent successfully.");
}
 
Here is a quick and dirty sketch that emulated your input data...
Code:
class FOO : public Stream {
    public:
    FOO(const char *sz)
        : _psz(sz) {}

    virtual int available() {
        return strlen(_psz);
    }
    virtual int read() {
        return (*_psz == 0) ? -1 : *_psz++;
    }
    virtual int peek() {
        return (*_psz == 0) ? -1 : *_psz;
    }
    virtual size_t write(uint8_t b) {
        return 0;
    }
    const char *_psz;
};

//5053 5232 4950 5613 1048 3249 5055 1310
FOO foo("254 128\r0 127\r\n");

void setup() {
    // put your setup code here, to run once:
    while (!Serial) {}
    Serial.begin(115200);
    Serial.println("Start of list");
    int ch = foo.read();
    for (;;) {
        while ( (ch !=  -1) && ((ch < '0') || (ch > '9'))) ch = foo.read();
        if (ch == -1) break;
        int next_num = 0;
        while ((ch >= '0') && (ch <= '9')) {
            next_num = next_num * 10 + ch - '0';
            ch = foo.read();
        }
        Serial.println(next_num);
    }
    Serial.println("End of list");
}

void loop() {
    // put your main code here, to run repeatedly:
}

Output:
Code:
Start of list
254
128
0
127
End of list
 
I have written the code and am doing the check on a small size 2x2 matrix.

I see you decided to follow 1 of the 3 suggestions I made in msg #8, but ignored the other 2.

I briefly considered spending some time to edit your code, for those other 2 suggestions. But I'm really not getting a clear idea of the actual contents of your "/mbyte2-2.txt" file. Maybe it really is exactly 4 bytes? Or maybe it's ASCII text as Kurt has been trying to explain how to parse? Maybe you said this earlier and I just haven't put time into carefully re-reading every message?

Really, I do want to help you. But I also have many other demands on my time. Even though I'm willing to edit and run code, and write these replies, I just can't spent that time when the details aren't even clear.

I do hope you'll consider editing your program to include all 3 of my suggestions. Then I can quickly run it here without guesswork, as can everyone else on this forum. We really do try to help here... but you need to understand everyone reading has limits to the amount of time and effort they can give (for free) to help you. If you edit your code for all 3 of my suggestions, I will help much more, and odds are pretty good others will too.
 
Thank you all for your support and desire to help.
The problem is now solved. The code presented in message 6 was used as a basis. Need to skip spaces and newline characters.
 
Back
Top