I need FRAM 101 help

Hello,
I am trying to build a project to measure temp remotely with DS18B20 sensors an Adafruit Trinket M0 and an Adafruit FRAM board ( I have an SPI version but ordered the I2c version to simplify and free up ports in case I need to measure altitude, I know its slower but shouldn't be a problem). I am lost. The example sketch works, but I am at a loss trying to figure out how to write or find a sketch to record and later read the FRAM. Is there such a thing as a 101 FRAM tutorial? Does it need different sketches to write and to read later?Whats the best way to translate the data to usable graphs?
Thank you.

Hi,
Is this topic in the correct category?

I thought so, but I am often wrong

Introductory tutorials is for tutorials you write. Project guidance seemed more appropriate.

Does Adafruit have anything? If not, I have some code I used to read and write calibration data to a FRAM. IIRC, their library just lets you read or write a single byte at a time.

Thank you @wildbill for fixing it. I went as far as the adafruit tutorial goes which is not much, just a test. I am very very green, this is my second project, for the first one I was lucky it was simpler and this forum is filled with standup people. I learned a bit to read the sketches, and modify them to suit my purpose (which led to horrible writing, and tons of basic mistakes that trained eyes catch immediately, but not me) So i am trying to learn more, I don't really know what writing a single byte means TBH, but I am always ready and willing to learn, I know this is doable, not too complicated, unless you are a neophyte like me.

Here's some code that uses the FRAM:

#include <Adafruit_FRAM_I2C.h>

const byte NoTools=8;
const uint32_t  StepsPerRotation=12800;          // Steps. In this version delays are used and every command to step provides a rising and falling edge.
const uint32_t StepsPerTool=StepsPerRotation/NoTools;

uint32_t BaseToolPositions[NoTools];             // Where is each tool in position. Initialized in setup. Calibration changes this
uint32_t ToolAdjustments[NoTools] = {0,0,0,0,0,0,0,0};    
uint32_t ActualToolPositions[NoTools];           // Base Tool positions plus Adjustments

Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();

void setup()
{
Serial.begin(115200);
while (!Serial);

Serial.println(__FILE__);  // Tell me the name of the file that was compiled to make this - useful version check. 
fram.begin();
SetDefaultToolPositions();
if(FramIsClean()) // If no data has been written to the first bytes in the FRAM, i.e. it's new
  {
  WriteToolPositionsToFram();  // Write the defaults to the FRAM
  }
ReadToolPositionsFromFram();   // Always read the tool positions in case there has been calibration
PrintToolPositions();
ApplyToolAdjustments();
}

void SetDefaultToolPositions()
{
for(unsigned int lp=0;lp<NoTools;lp++)
  {
  BaseToolPositions[lp]= (uint32_t)StepsPerTool*lp;   
  }
}

void PrintToolPositions()
{
for(uint16_t lp=0;lp<NoTools;lp++)
  {
  Serial.print(F("Tool: "));  
  Serial.print(lp+1);  
  Serial.print(F(" Base Position: "));
  Serial.println(BaseToolPositions[lp]);      
  Serial.print(F(" Adjusted Position: "));
  Serial.println(ActualToolPositions[lp]);      
  }
}

void ApplyToolAdjustments()
{
for(uint16_t lp=0;lp<NoTools;lp++)
  {
  ActualToolPositions[lp]=BaseToolPositions[lp]+ToolAdjustments[lp];    
  }
}

void loop()
{
}

/*
 FRAM routines. All you can do with the Adafruit library is read or write one byte at a time from any address

 Write the tool positions array to FRAM. 
 Use a byte pointer to write the bytes that make up the array, one at a time.
 */
 
void WriteToolPositionsToFram()
{
uint8_t *ptr=(uint8_t*)BaseToolPositions;
for(uint16_t lp=0;lp<sizeof BaseToolPositions;lp++)
  {
  fram.write8(lp,ptr[lp]);
  }
}

// Read the tool positions array from FRAM. 
// Use a byte pointer to read the bytes that make up the array, one at a time.

void ReadToolPositionsFromFram()
{
uint8_t *ptr=(uint8_t*)BaseToolPositions;
for(uint16_t lp=0;lp<sizeof BaseToolPositions;lp++)
  {
  ptr[lp]=fram.read8(lp);
  }
}

/*
 Check whether anything has been written to the first few bytes of the FRAM.

 If anything has, we will read the tool positions from FRAM. If not, we will assume the FRAM is new and write the defaults out.
 Note that FramIsClean just tells us what to do. The routines above actually do it.
 */
 
bool FramIsClean()
{
for(uint16_t lp=0;lp<sizeof BaseToolPositions;lp++)
  {
  uint8_t byt = fram.read8(lp);
  if(byt !=0)
    {
    return false;  
    }
  }
return true;  
}

As will be obvious, it came from another program but it shows you how to read and write data. What data (and how much) do you plan to collect?

I've not looked, but doesn't Adafruit have an example for the FRAM boards?

Yes, a basic one, or at least, one I have no Idea how to modify to suit what I need it to do. :confused:

It sounds like your confusion is more about the general logic of a data-logging application in general, rather than anything specific to FRAM.

Try putting what you want into a careful description:

  1. The data required should be in CSV form with each line containing a timestamp, the temperature, and ....
  2. It's OK for the data to be sent to the console, and then cut&pasted into the analysis program.
  3. The sketch should either record samples, or it should dump pre-recorded samples to the console. This could be two sketches, or just one.
  4. The board will be powered by a battery when collecting samples, but by the USB port when dumping data. Maybe this can be used to pick which mode ?
  1. The data required should be in CSV form with each line containing a timestamp, the temperature, and ....
    Timestamp, Temperature, sensor signature or number (3 sensors) If i can get greedy also an altitude measurement if i can add an Adafruit BMP280 I2C Barometric Pressure & Altitude Sensor -
    Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor [STEMMA QT] : ID 2651 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits

  2. It's OK for the data to be sent to the console, and then cut&pasted into the analysis program.
    YES!

  3. The sketch should either record samples, or it should dump pre-recorded samples to the console. This could be two sketches, or just one.
    YES! I can work with 2 sketches

  4. The board will be powered by a battery when collecting samples, but by the USB port when dumping data. Maybe this can be used to pick which mode ?
    YES! remote recording powered by CR2032 batteries and then I can dump at home with USB

Thank you again :grinning:

Ok - one more issue:

  • The number of samples I need to store is N, between data dumps to the PC. Therefore, with the XXX kbyte FRAM I have, I should:
  1. Not worry at all about storage efficiency.
  2. Store the data in the most efficient manner possible.
  3. Find a bigger FRAM.

2160 readings from 3 temp sensors :grimacing: is that too much? I can fit 2 FRAMS in there I think.
Its a balloon flight, most times 2 hrs going up 5-15 hrs up there and then return. I was hoping for readings every 30 seconds, nut the truth is the most important phase is while going up, the time its stationary up there I can live with readings every 5 minutes. I would love to add an altimeter but #1 not sure if its too much, #2 I have not found an altimeter that will measure up to 38km, #3 I don't want to push my luck

This is what I need

And this is what I wish, but with a Altimeter Module MS5607 that has been tested up to 120K feet instead of the Adafruit depicted

No. 512K is a lot. The DS18B20 library returns a float - four bytes. Let's assume that the altitude reading is the same size. So a single sample is 16 bytes. Twenty hours of samples at 30S intervals is 2400 samples. So you need less than 40K to store them.

You will need code to read the data back & emit it in a form where you can graph it in Excel or whatever, but there is no need to store it in that format.

There's no point to it here, but note that the temperature sensor actually returns 12 bits at maximum sensitivity, so using four bytes to store it is wasteful and you could cut your memory needs on the Fram in half at least.

Thank you, I see tor door can be opened, this is much better than before. How do I know how many addresses are in my FRAM?How about Byte values? I am looking at adafruit’s sketch and trying to make sense of it to see if I can start tinkering from it
Thank you again

The choices are 256K or 512K bytes (K =1024).

That's fine. As wildbill said, a float is only 4 bytes.
But my point was that even if you go to a more verbose format, something text-like:

time            alt        temp1  temp2  temp3
HH:MM:SS,22345, 025.45, 025.80, 025.02

(40 bytes, including the newline), and still have room for over 6000 samples in your 256kbyte FRAM chip.

I don't know if that's easier to do than storing the info in binary (about half the size without getting tricky), but it's a worry you don't have...

Now something just like this would be lovely!
Thank you very much for the advice guys, this is all very valuable info you have given me, I can apply it in an abstract setting, for designing functionality and understanding the limitations of the system I am trying to build with the current components, but the knowledge gap is still there in terms of getting down to write code I just don't understand (its not you, its me) :woozy_face: If I were to accept defeat. Where would you suggest I turn for help next?

There is section of the forum where you can request paid help if you just want the job completed. Generally though, if you post your coding attempts, people will give you plenty of help with it for free.

Alternatively, can you find a college or high school student who has taken some programming courses to help? Fellow balloonists perhaps. What you're trying to do isn't particularly difficult, maybe play around with some FRAM examples to get the light bulb to go on.

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