I got my hands on 2 FRAM breakout, one I2C (Adafruit I2C Non-Volatile FRAM Breakout - 256Kbit / 32KByte) and one SPI (MB85RS4MT).
My goal is to test the difference in logging speed between these two, I'm logging struc in order to be able to log different data types. I'm using two standard Arduino Uno (one for each breakout) and the standard Adafruit Fram libraries.
So far I've been able to log data on I2C breakout.
- Code: Select all | TOGGLE FULL SIZE
/*
Based on :
https://arduino.stackexchange.com/questions/76951/arduino-i2c-external-32kb-fram-data-organization
https://forum.arduino.cc/index.php?topic=720754.new#new
https://forum.arduino.cc/index.php?topic=618910.0
*/
#include <Wire.h>
#include "Adafruit_FRAM_I2C.h"
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();
uint16_t framAddr = 0;
unsigned long nbWrites = 0;
unsigned long logTime = 0;
unsigned long logTimer = 0;
unsigned long averageLogTime = 0;
unsigned long maxLogTime = 0;
unsigned long nbLogLess100us = 0;
unsigned long nbLogLess1000us = 0;
unsigned long nbLogMore1000us = 0;
unsigned long nbLogMore10000us = 0;
struct program_data {
int variable0;
int variable1;
int variable2;
int variable3;
int variable4;
int variable5;
int variable6;
int variable7;
int variable8;
int variable9;
} data;
int address = 0;
int i = 0;
void setup() {
Serial.begin(115200);
fram.begin(0x50);
}
void loop() {
// Start logTimer
logTimer = micros();
// Get data
GetData();
// Save data
SaveData(&data);
// Stop logTimer
logTime = micros() - logTimer;
averageLogTime += logTime;
// Log Time statistics
LogStats();
nbWrites++;
// Print data
if (nbWrites > 10) {
address = 0;
for (int n = 0; n < nbWrites; n++) {
RestoreData(&data);
}
EndStats();
while (true);
}
}
void GetData() {
data.variable0 = nbWrites;
data.variable1 = 100;
data.variable2 = 100;
data.variable3 = 100;
data.variable4 = 100;
data.variable5 = 100;
data.variable6 = 100;
data.variable7 = 100;
data.variable8 = 100;
data.variable9 = 100;
}
void SaveData(struct program_data *data_ptr) {
byte *ptr = (byte *)data_ptr;
for (i = 0; i < sizeof(struct program_data); i++) {
fram.write8(address + i, ptr[i]);
}
address = address + i;
}
void RestoreData(struct program_data *data_ptr) {
byte *ptr = (byte *)data_ptr;
for (i = 0; i < sizeof(struct program_data); i++) {
ptr[i] = fram.read8(address + i);
}
address = address + i;
// Print all data
Serial.print(data.variable0); Serial.print(",");
Serial.print(data.variable1); Serial.print(",");
Serial.print(data.variable2); Serial.print(",");
Serial.print(data.variable3); Serial.print(",");
Serial.print(data.variable4); Serial.print(",");
Serial.print(data.variable5); Serial.print(",");
Serial.print(data.variable6); Serial.print(",");
Serial.print(data.variable7); Serial.print(",");
Serial.print(data.variable8); Serial.print(",");
Serial.print(data.variable9); Serial.print(",");
Serial.println("");
}
void LogStats() {
if (logTime > maxLogTime) {
maxLogTime = logTime;
}
if (logTime <= 100) {
nbLogLess100us++;
}
if (logTime > 100 && logTime <= 1000) {
nbLogLess1000us++;
}
if (logTime > 1000 && logTime <= 10000) {
nbLogMore1000us++;
}
if (logTime > 10000) {
nbLogMore10000us++;
}
}
void EndStats() {
Serial.println("");
Serial.print("Average Log Time"); Serial.print("\t"); Serial.println(averageLogTime / nbWrites);
Serial.print("Max Log Time"); Serial.print("\t"); Serial.print("\t"); Serial.println(maxLogTime);
Serial.print("Log Time <100us"); Serial.print("\t"); Serial.print("\t"); Serial.print(nbLogLess100us); Serial.print("\t"); Serial.println(((nbLogLess100us * 100.00) / nbWrites), 1);
Serial.print("Log Time <1000us"); Serial.print("\t"); Serial.print(nbLogLess1000us); Serial.print("\t"); Serial.println(((nbLogLess1000us * 100.00) / nbWrites), 1);
Serial.print("Log Time >1000us"); Serial.print("\t"); Serial.print(nbLogMore1000us); Serial.print("\t"); Serial.println(((nbLogMore1000us * 100.00) / nbWrites), 1);
Serial.print("Log Time >10000us"); Serial.print("\t"); Serial.print(nbLogMore10000us); Serial.print("\t"); Serial.println(((nbLogMore10000us * 100.00) / nbWrites), 1);
}
And I'm get thoses results:
- Code: Select all | TOGGLE FULL SIZE
0,100,100,100,100,100,100,100,100,100,
1,100,100,100,100,100,100,100,100,100,
2,100,100,100,100,100,100,100,100,100,
3,100,100,100,100,100,100,100,100,100,
4,100,100,100,100,100,100,100,100,100,
5,100,100,100,100,100,100,100,100,100,
6,100,100,100,100,100,100,100,100,100,
7,100,100,100,100,100,100,100,100,100,
8,100,100,100,100,100,100,100,100,100,
9,100,100,100,100,100,100,100,100,100,
10,100,100,100,100,100,100,100,100,100,
Average Log Time 8490
Max Log Time 8496
Log Time <100us 0 0.0
Log Time <1000us 0 0.0
Log Time >1000us 11 100.0
Log Time >10000us 0 0.0
Code is cleary working.
I then wanted to test the same code (with some minor changes) for the SPI breakout, like so :
- Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include "Adafruit_FRAM_SPI.h"
/* Example code for the Adafruit SPI FRAM breakout */
uint8_t FRAM_CS = 10;
Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_CS); // use hardware SPI
//uint8_t FRAM_SCK = 13;
//uint8_t FRAM_MISO = 12;
//uint8_t FRAM_MOSI = 11;
//Or use software SPI, any pins!
//Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_SCK, FRAM_MISO, FRAM_MOSI, FRAM_CS);
uint16_t addr = 0;
unsigned long nbWrites = 0;
unsigned long logTime = 0;
unsigned long logTimer = 0;
unsigned long averageLogTime = 0;
unsigned long maxLogTime = 0;
unsigned long nbLogLess100us = 0;
unsigned long nbLogLess1000us = 0;
unsigned long nbLogMore1000us = 0;
unsigned long nbLogMore10000us = 0;
struct program_data {
int variable0;
int variable1;
int variable2;
int variable3;
int variable4;
int variable5;
int variable6;
int variable7;
int variable8;
int variable9;
} data;
int address = 0;
int i = 0;
void setup() {
Serial.begin(115200);
if (fram.begin()) {
Serial.println("Found SPI FRAM");
} else {
Serial.println("No SPI FRAM found ... check your connections\r\n");
while (1);
}
}
void loop() {
// Start logTimer
logTimer = micros();
// Get data
GetData();
// Save data
SaveData(&data);
// Stop logTimer
logTime = micros() - logTimer;
averageLogTime += logTime;
// Log Time statistics
LogStats();
nbWrites++;
// Print data
if (nbWrites > 10) {
address = 0;
for (int n = 0; n < nbWrites; n++) {
RestoreData(&data);
}
EndStats();
while (true);
}
}
void GetData() {
data.variable0 = nbWrites;
data.variable1 = 100;
data.variable2 = 100;
data.variable3 = 100;
data.variable4 = 100;
data.variable5 = 100;
data.variable6 = 100;
data.variable7 = 100;
data.variable8 = 100;
data.variable9 = 100;
}
void SaveData(struct program_data *data_ptr) {
byte *ptr = (byte *)data_ptr;
fram.writeEnable(true);
for (i = 0; i < sizeof(struct program_data); i++) {
fram.write8(address + i, ptr[i]);
}
fram.writeEnable(false);
address = address + i;
}
void RestoreData(struct program_data *data_ptr) {
byte *ptr = (byte *)data_ptr;
for (i = 0; i < sizeof(struct program_data); i++) {
ptr[i] = fram.read8(address + i);
}
address = address + i;
// Print all data
Serial.print(data.variable0); Serial.print(",");
Serial.print(data.variable1); Serial.print(",");
Serial.print(data.variable2); Serial.print(",");
Serial.print(data.variable3); Serial.print(",");
Serial.print(data.variable4); Serial.print(",");
Serial.print(data.variable5); Serial.print(",");
Serial.print(data.variable6); Serial.print(",");
Serial.print(data.variable7); Serial.print(",");
Serial.print(data.variable8); Serial.print(",");
Serial.print(data.variable9); Serial.print(",");
Serial.println("");
}
void LogStats() {
if (logTime > maxLogTime) {
maxLogTime = logTime;
}
if (logTime <= 100) {
nbLogLess100us++;
}
if (logTime > 100 && logTime <= 1000) {
nbLogLess1000us++;
}
if (logTime > 1000 && logTime <= 10000) {
nbLogMore1000us++;
}
if (logTime > 10000) {
nbLogMore10000us++;
}
}
void EndStats() {
Serial.println("");
Serial.print("Average Log Time"); Serial.print("\t"); Serial.println(averageLogTime / nbWrites);
Serial.print("Max Log Time"); Serial.print("\t"); Serial.print("\t"); Serial.println(maxLogTime);
Serial.print("Log Time <100us"); Serial.print("\t"); Serial.print("\t"); Serial.print(nbLogLess100us); Serial.print("\t"); Serial.println(((nbLogLess100us * 100.00) / nbWrites), 1);
Serial.print("Log Time <1000us"); Serial.print("\t"); Serial.print(nbLogLess1000us); Serial.print("\t"); Serial.println(((nbLogLess1000us * 100.00) / nbWrites), 1);
Serial.print("Log Time >1000us"); Serial.print("\t"); Serial.print(nbLogMore1000us); Serial.print("\t"); Serial.println(((nbLogMore1000us * 100.00) / nbWrites), 1);
Serial.print("Log Time >10000us"); Serial.print("\t"); Serial.print(nbLogMore10000us); Serial.print("\t"); Serial.println(((nbLogMore10000us * 100.00) / nbWrites), 1);
}
But I'm getting only 0 !
- Code: Select all | TOGGLE FULL SIZE
Found SPI FRAM
127,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
Average Log Time 1473
Max Log Time 1532
Log Time <100us 0 0.0
Log Time <1000us 0 0.0
Log Time >1000us 11 100.0
Log Time >10000us 0 0.0
I should add that the SPI breakout is working, I've been able to log on it.
Why is the SPI version not working ? Any ideas ?
Any help is greatly appreciated. Thanks