Go Down

Topic: External storage for Arduino (Read 1 time) previous topic - next topic

Fanavaran

Hello guys
I'm working on a Gps logger and I need to save some records on a storage.
the minimum required space is 16megabytes.
what storage do you guys recommend beside the SD card.
i need it to be embedded.

noob314

#1
Dec 07, 2019, 08:22 am Last Edit: Dec 07, 2019, 08:27 am by noob314
Winbond flash memory ICs, perhaps. For instance W25Q128 or even larger than 16MB, they are quite cheap and there is Arduino lib to support them.

I have used it with some projects.


Fanavaran

Actually i already got one. W25Q128!
I've heard about some limitation in writing data on it.
it would loose the sectors gradually !!?

noob314

#3
Dec 07, 2019, 09:12 am Last Edit: Dec 07, 2019, 09:31 am by noob314
It is standard flash memory and these Winbond chips are used widely in almost any electronic today which require large storage space for firmware. But also can be used for logging.

- More than 100,000 erase/program cycles
- More than 20-year data retention

https://www.winbond.com/resource-files/w25q128fv%20rev.l%2008242015.pdf

Not extremely durable as SSD nowadays, but for these projects require large amount of storage space are ideal and it will last very long time, if you do not need mobile storage as SD card. Anyway, I have even made small board and headers for easier replacement. There is no issue so far.

Fanavaran

#4
Dec 07, 2019, 09:31 am Last Edit: Dec 07, 2019, 09:38 am by Fanavaran
Looks fair !
So, since you had some project with Winbond , would you plz help me with wiring and coding ?
I'm extremely noob :D
I'd some problem with WP pin. should i connect it to vcc or gnd !?
in vcc mode , when i try to write and read something on it, it returns 0 !
in gnd mode it won't returns anything !
is it coding issue or wiring ?
here is the sketch

Code: [Select]
#define DATAOUT 15//MOSI
#define DATAIN  16//MISO
#define SPICLOCK  17//sck
#define SLAVESELECT 14//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
   spi_transfer(buffer[I]); //write data byte
  }
 digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
 Serial.print('h');
  Serial.print('i');
  Serial.print('\n');//debug
 delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n');
  address++;
  if (address == 128)
    address = 0;
  delay(500); //pause for readability
}

noob314

#5
Dec 07, 2019, 12:01 pm Last Edit: Dec 07, 2019, 02:53 pm by noob314
I will provide you as many info I can, but later in the day. I would have also to dig out such old project... Feel free to contact me via PM.

Those are minimum steps for now:
1. First download datasheet.
2. Get library. I believe I have used this one: https://github.com/PaulStoffregen/SerialFlash
3. Notice the chip is specified for 3.3V. That means you need to power chip by 3.3V and have level shifter if you have 5V Arduino board.  Otherwise you may fry your memory chip. If you have 3.3V Arduino board or just a 328p, that would be much easier.

WP pin is "Write Protected" pin and is marked in datasheet as /WP (active low), which means it have to be connect to 3.3V in order to allow writing. When active (connected to GND), that pin ensure nothing will be wrote on the chip in order to protect content.

Do not use your posted code, use suitable library instead.

gilshultz

 Have you considered FRAM (Ferroelectric Random Access Memory), not the cheapest but definitively reliably.   It's similar to Static random-access memory, only with a ferroelectric layer instead of a dielectric layer. This gives it stable handling (the bytes you write are non-volatile) with dynamic responsiveness (you can write them very fast!). Some of the advantages I see in FRAM are high speed reading and writing, non-volatile storage (it remembers its contents without needing power or battery backup), virtually unlimited read / write cycles - you can't wear it out unlike some other types of non-volatile memory. To get started  try this link: https://www.adafruit.com/product/1897  There board has a write enable input so you can lock it down and read it on another machine without worry about trashing the date. There are no delays like you get with SD cards. It is easy to use them, with SPI or I2C. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

 

Fanavaran

Each byte can be read/written 10,000,000,000,000 times !! Sounds great ! but i need at least 16MB !

Fanavaran

I will provide you as many info I can, but later in the day. I would have also to dig out such old project... Feel free to contact me via PM.

Those are minimum steps for now:
1. First download datasheet.
2. Get library. I believe I have used this one: https://github.com/PaulStoffregen/SerialFlash
3. Notice the chip is specified for 3.3V. That means you need to power chip by 3.3V and have level shifter if you have 5V Arduino board.  Otherwise you may fry your memory chip. If you have 3.3V Arduino board or just a 328p, that would be much easier.

WP pin is "Write Protected" pin and is marked in datasheet as /WP (active low), which means it have to be connect to 3.3V in order to allow writing. When active (connected to GND), that pin ensure nothing will be wrote on the chip in order to protect content.

Do not use your posted code, use suitable library instead.

i all steps, the problem was WP. thanks to you i'm gonna solve it.

noob314

#9
Dec 12, 2019, 01:24 pm Last Edit: Dec 12, 2019, 01:28 pm by noob314
I have attached fixed one of examples from that library in order to compile on UNO/NANO without an issue. Only I have inserted F() macros for all string literals, since this example is full of it and RAM was critical.

Can you confirm is it working and feedback results from "Serial Monitor" log, if all passed fine?

Go Up