Saving a Long to SPI FRAM

Hi there! I'm using an SPI FRAM Breakout board to store accelerometer data where it won't be deleted when power is lost. I'm having some issues with storing a Long variable type. My current understanding is that I am supposed to take the variable, then break it up into component bytes. These values get stored at a defined address, then can be accessed with calls to the same address. I've included my code and the output below.

I'm still rather new to FRAM and saving data outside of the board SRAM

Here is my code written out:

#include "Wire.h"
#include "SPI.h"
#include "Adafruit_FRAM_SPI.h"

const int FRAM_ADDRESS = 0;
const int8_t FRAM_CS = 10;

Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_CS);  // use hardware SPI

const uint8_t FRAM_SCK = 13;
const uint8_t FRAM_MISO = 12;
const uint8_t FRAM_MOSI = 11;


void setup() {
    Serial.begin(9600);
  if (fram.begin()) {
    Serial.println("Found SPI FRAM!");
    } 
  else {
    Serial.println("No SPI FRAM found ... check your connections\r\n");
    while (1);
  }
  
  const int FRAM_ADDRESS = 0x20;
  long varSent = 255;
  long varReceived;
  
  Serial.println();
  Serial.print("Input: "); Serial.println(varSent);
    
  fram.writeEnable(true);
    for(int i = 0; i<sizeof(varSent); i++) {
      fram.write8(FRAM_ADDRESS+i, ((byte *)&varSent)[i]);
      Serial.print(FRAM_ADDRESS+i);
      Serial.print(": ");
      Serial.print(((byte *)varSent)[i]);
      Serial.print(" ");
    }
  fram.writeEnable(false);
  
  Serial.println();
    for(int i = 0; i<sizeof(varSent); i++) {
      ((byte *)&varReceived)[i] = fram.read8(FRAM_ADDRESS+i);
      Serial.print(FRAM_ADDRESS+i);
      Serial.print(": ");    
      Serial.print(fram.read8(FRAM_ADDRESS+i));
      Serial.print(" ");
    }
    Serial.println();
  Serial.print("Output: "); Serial.println(varReceived);
  Serial.println();
}

And here is the Serial Monitor output for a few random inputs:
image

Can you tell me what I am doing wrong? My end goal is to have an array of long numbers being stored in FRAM, but I'm struggling with my test case.

You can try this

uint8_t tmp[4];

long someValue = 12345;

memcpy(tmp, (uint8_t *) &someValue, 4);

for(int i = 0; i<4; i++) {
      fram.write8(FRAM_ADDRESS+i, tmp[i]);
	  }

Thank you for the suggestion, it's working better, but still seems to have issues writing all the values. The first value written to the FRAM Address appears to be correct, however, it does not appear to be writing the next three bytes. The top four numbers are the values of tmp[i] from i = 0-3. The bottom values are what is being read from the system, and the latter three numbers never change. Do you have any ideas on how to fix this?

Below are the write/read loops that I ran to get the Serial Monitor Output below:

const int FRAM_ADDRESS = 0x20;
  uint8_t tmp[4];
  long varSent = 12345;
  long varReceived;

  memcpy(tmp,(uint8_t *) &varSent, 4);
  
  Serial.println();
  Serial.print("Input: "); Serial.println(varSent);
    
  fram.writeEnable(true);
    for(int i = 0; i<4; i++) {
      fram.write8(FRAM_ADDRESS+i, tmp[i]);
      Serial.print(FRAM_ADDRESS+i);
      Serial.print(": ");
      Serial.print(tmp[i]);
      Serial.print(" ");
    }
  fram.writeEnable(false);
  
  Serial.println();
    for(int i = 0; i<4; i++) {
      ((byte *)&varReceived)[i] = fram.read8(FRAM_ADDRESS+i);
      Serial.print(FRAM_ADDRESS+i);
      Serial.print(": ");    
      Serial.print(fram.read8(FRAM_ADDRESS+i));
      Serial.print(" ");
    }
    Serial.println();
  Serial.print("Output: "); Serial.println(varReceived);
  Serial.println();

image

Can you try replacing Serial.print(tmp[i])

with

Serial.print(tmp[i], HEX) instead.

Also, you can re-use variables so instead of doing this weird nesting,

    for(int i = 0; i<4; i++) {
      ((byte *)&varReceived)[i] = fram.read8(FRAM_ADDRESS+i);
      Serial.print(FRAM_ADDRESS+i);
      Serial.print(": ");    
      Serial.print(fram.read8(FRAM_ADDRESS+i));
      Serial.print(" ");
    }

Not exactly sure how you end up with this piece of code here

((byte *)&varReceived)[i]

You can make it more readable with

for(int i = 0; i<4; i++)
{
	tmp[i] = fram.read8(FRAM_ADDRESS+i);
	Serial.print(FRAM_ADDRESS+i);
	Serial.print(": ");    
	Serial.print(tmp[i]);
	Serial.print(" ");
}

Can you explain how using HEX variables would help? I'm not familiar with those.

That came from another topic on this forum posted by another user who was attempting to do a similar task. The link is at the bottom of the reply. This line of code allows me to recreate a long variable using the four integers read from FRAM.

((byte *)&varReceived)[i] = fram.read8(FRAM_ADDRESS+i);

Link to Similar Forum Post:

The Serial.print() function is used for testing, so I can diagnose any issues with the code. Once the problem is solved, it will be removed. I'm not concerned about readability, as long as it works.

  Serial.print(fram.read8(FRAM_ADDRESS+i));

I need my code to take a long (varSent), then write it in FRAM. Then, when it is called in a separate function, to be able to read the data and reconstitute it into a long (varRecieved). The issue appears to be in writing to FRAM. Based on the Serial.print() outputs, my code seems to be doing the following:

  1. Break up the long variable into integers for writing in tmp
  2. Write tmp[0] to FRAM Address 32, however, it leaves addresses 33-35 untouched
  3. Read variables from address 32-35
  4. Reconstitute long variable from received integers

I've noticed that the output of:

  Serial.print(fram.read8(FRAM_ADDRESS+i));

Always displays tmp[0] 10 0 0, regardless of whatever data is intended to be written there. That is the issue I'm trying to solve.

  1. Break up the long variable into integers for writing in tmp
memcpy(tmp, (uint8_t *) &testNumber, 4);
  1. Write tmp[0] to FRAM Address 32, however, it leaves addresses 33-35 untouched
  2. Read variables from address 32-35
  3. Reconstitute long variable from received integers

You do the opposite

for(uint8_t i=0; i<4; i++) {
	tmp[i] = fram.read(i);
}

memcpy((uint8_t *) &testNumber, tmp, 4);

Test writing and reading some ASCII character in your FRAM, maybe something is wrong with the library

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.