Need Some Help With My Code

Short and Simple but I'm not a programmer I have 90% of the work done I need help with 2 or 3 things then someone to look over code and maybe optimize it.

My current issue is writing to a Adafruit fram module, I have the module up and running with test script but need to write long numbers across the fram and increment it regularly from another part of script. Like I said I am not a programmer and I'm still learning..

Can anyone help ? i'm reading everything i can but just can't figure this out I'm learning and willing to take any help anyone could give to increase my knowledge.

Thanks in advance

P.S. I edited this because I have learned!, That learning is better than asking for someone to finish up code for a price. I want to learn but it's hard if you don't understand everything. And I'm the first to admit I don't understand all of it.. I do give credit where credit is due and any help given will be credited in my finished product.

thought i would post the code i am using so far to give idea…

#include <SPI.h>
#include "Adafruit_FRAM_SPI.h"

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;
uint16_t          addr = 0;

int odovalue = 211;  //example start mileage wil comment out for later use if needed

void setup(void) {
  
  Serial.begin(9600);
  
  if (fram.begin()) {
    Serial.println("Checking FRAM");
  } else {
    Serial.println("No SPI FRAM found ... check your connections\r\n");
    while (1);
  }
  
  // Read the first byte
  uint8_t mileage = fram.read8(0x0);
  Serial.print("Mileage "); Serial.print(mileage);

  // write new value
  fram.writeEnable(true);
  fram.write8(0x0, odovalue);
  fram.writeEnable(false);


  }

void loop(void) {

}

So here is what I need to do, I need to write the initial value to the FRAM lets say inital value is 102395.25 I need that to be the starting value then when my process runs it will need to read that value from the FRAM and use the value then write back the new updated value that is passed to it from the rest of the script. the script updates the value of the odovalue every .25 of a mile

i know every address can only store up to 255 this needs to spread out on the FRAM to cover the large value and I have no clue how to do it. I have tried google to my wits end to figure it out but im not a programmer and im learning as I go.

hope this helps with what I am trying to do… I don’t think its difficult just i have not learned enough yet.

My current issue is writing to a Adafruit fram module

What is a fram module?

I need to write the initial value to the FRAM lets say inital value is 102395.25

That isn't a long. That is a float.

i know every address can only store up to 255 this needs to spread out on the FRAM to cover the large value and I have no clue how to do it.

A float is always 4 bytes. Using a union, you can make a float and a 4 byte array occupy the same memory. The advantage of this is that you can simply assign a float to the memory location, the byte array is populated, too. Write the bytes to EEPROM.

When needed, read the bytes from EEPROM, populating the byte array, and the float will be valued, too.

union u
{
   float f;
   byte b[4];
};

u someName;

someName.f = 102395.25;

// Write someName.b[0], someName.b[1], someName.b[2], and someName.b[3] to EEPROM

PaulS:
What is a fram module?

Sorry its a FRAM Breakout board not Module

That isn't a long. That is a float.
A float is always 4 bytes. Using a union, you can make a float and a 4 byte array occupy the same memory. The advantage of this is that you can simply assign a float to the memory location, the byte array is populated, too. Write the bytes to EEPROM.

^^ Brain overload....

When needed, read the bytes from EEPROM, populating the byte array, and the float will be valued, too.

union u

{
  float f;
  byte b[4];
};

u someName;

someName.f = 102395.25;

// Write someName.b[0], someName.b[1], someName.b[2], and someName.b[3] to EEPROM

See this is my problem I don't know this stuff yet... I guess i need to go learn how to Float...

I hate to admit it but i'm still confused.. I will go read about floats and unions...

Thanks for the homework....

I guess i need to go learn how to Float…

The YMCA offers swimming classes. Lesson 1 involves learning to float.

PaulS:
The YMCA offers swimming classes. Lesson 1 involves learning to float.

Nice, Now if they would offer some union classes I'd be in business...

Blue-Ice:
Nice, Now if they would offer some union classes I'd be in business...

You could probably find a local union hall that had classes.

to write out a float one byte at a time:

  float myValue_mi;
  const int FRAM_ADDRESS = 0;

  for(int i = 0; i<sizeof(myValue_mi); i++) {
    ((byte *)&myValue_mi)[i] = fram.read8(FRAM_ADDRESS + i);
  }

  fram.writeEnable(true);
  for(int i = 0; i<sizeof(myValue_mi); i++) {
    fram.write8(FRAM_ADDRESS + i, ((byte *)&myValue_mi)[i]);
  }
  fram.writeEnable(false);

Oh, btw: never use floats for exact values. If your odometer works in units of 10ths or 100ths of a mile, store the value as a int or long or even long long in that unit. I always suffix variable names with the unit of measurement, so I don’t crash my probe on mars and waste millions of dollars.

  long long myValue_mi00;
  const int FRAM_ADDRESS = 0;

  for(int i = 0; i<sizeof(myValue_mi00); i++) {
    ((byte *)&myValue_mi00)[i] = fram.read8(FRAM_ADDRESS + i);
  }

  fram.writeEnable(true);
  for(int i = 0; i<sizeof(myValue_mi00); i++) {
    fram.write8(FRAM_ADDRESS + i, ((byte *)&myValue_mi00)[i]);
  }
  fram.writeEnable(false);

PaulMurrayCbr:
to write out a float one byte at a time:

  float myValue_mi;

const int FRAM_ADDRESS = 0;

for(int i = 0; i<sizeof(myValue_mi); i++) {
    ((byte *)&myValue_mi)[i] = fram.read8(FRAM_ADDRESS + i);
  }

fram.writeEnable(true);
  for(int i = 0; i<sizeof(myValue_mi); i++) {
    fram.write8(FRAM_ADDRESS + i, ((byte *)&myValue_mi)[i]);
  }
  fram.writeEnable(false);





Oh, btw: never use floats for exact values. If your odometer works in units of 10ths or 100ths of a mile, store the value as a int or long or even long long in that unit. I always suffix variable names with the unit of measurement, so I don't crash my probe on mars and waste millions of dollars.



long long myValue_mi00;
  const int FRAM_ADDRESS = 0;

for(int i = 0; i<sizeof(myValue_mi00); i++) {
    ((byte *)&myValue_mi00)[i] = fram.read8(FRAM_ADDRESS + i);
  }

fram.writeEnable(true);
  for(int i = 0; i<sizeof(myValue_mi00); i++) {
    fram.write8(FRAM_ADDRESS + i, ((byte *)&myValue_mi00)[i]);
  }
  fram.writeEnable(false);

Thanks I’ll give that a try and see how badly i can muck it up. :slight_smile:

PaulS:
That isn't a long. That is a float.

Never use floats to store things that have exact values.

Long, Short, Float.

I'm Short
I can not Float
My Socks are Long

Makes no sense to me..

Anyways have not had time to get this done too much work not enough time to finish the last bit of program for the display.. Just no time..

I'll report in again..

Paul,

Thanks for the help. I can now write to the fram with a long number I used the code you helped me with to test with and I am 90% successful in the writing I only have a issue writing and displaying the decimal place. I can get it to write the 123456781 but not 12345681.25 maybe it does write it but like i said before I an mot a pro at this and learning my way around still I finally had some time to mess with it and got it to write. Any pointers on how to write and display the .25 portion of the number?

BTW I am only updating every .25 of a mile i did change it to a float and it returns a decimal place but not .25 no matter what i put for decimal it displays .00

#include <SPI.h>
#include "Adafruit_FRAM_SPI.h"
uint8_t FRAM_CS = 10;
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;

long odoValue = 12345681.25;

void setup(void) {
  
  Serial.begin(9600);
  
  // Read the starting odometer reading from FRAM and print to monitor for testing
  uint8_t test = fram.read8(0x0);
  Serial.print("Odometer Reading "); Serial.print(odoValue); Serial.println(" Miles");


long long odoValue;

  const int FRAM_ADDRESS = 0x0;

  for(int i = 0; i<sizeof(odoValue); i++) {
    ((byte *)&odoValue)[i] = fram.read8(FRAM_ADDRESS + i);
  }

  fram.writeEnable(true);
  for(int i = 0; i<sizeof(odoValue); i++) {
    fram.write8(FRAM_ADDRESS + i, ((byte *)&odoValue)[i]);
  }
  fram.writeEnable(false);
}
 

void loop(void) {

}
long odoValue = 12345681.25;

You don't understand that long is an integer type, do you?

The point was to not use/store floats unnecessarily. The point was not to NEVER use floats.

PaulS:

long odoValue = 12345681.25;

You don't understand that long is an integer type, do you?

The point was to not use/store floats unnecessarily. The point was not to NEVER use floats.

You are correct. I am trying to figure this out and reading a zillions things about it all. I played with float long long double all kind of things. I'm still learning and adapting what I learn to get my project moving in a forward fashion. I have order a book i think it was beginner arduino or arduino for dummies I can't remember now (don't have the book yet). Yes I'm learning and I'm trying to learn more. My project is a Digital dash for my Motorcycle and so far I have GPS based speed, tempo sensors, fuel sensors, tach all working this is my last bit and all it's all new to me so I'm trying to learn as I go what the effects of all the different formats of items.

as for never using floats i wonder why that is? I look at a lot of other code as i'm trying to learn and I see floats used for similar things, but then it looks like they are storing them as integer instead, so I assume that they are reading it as a float then converting it to a integer or long maybe then finally saving it as a float. maybe i'm 100% wrong and don't understand the effects yet.

So I ask questions. and then I learn what happens with the answers.

I can work with basic information and learn from it.

Yes I understand that the long can only return the number without the decimal and that is why I asked the question because if i use a float i can return the number to some extent with the decimal..

You state never use floats, are you saying never ever use floats ? Or just not for precise things ?

as for never using floats i wonder why that is?

No one has said "NEVER USE FLOATS". The advice is to minimize the use of floats, as much as possible. Unlike a PC, the Arduino does not have a floating point processor that speeds up working with floats and doubles. So, math using floats is slow. If you want to show a speed as a fractional value once a second, use floating point arithmetic. If you need to know the speed, in 100ths of a meter 100000 times a second, don't use floats. Keep the speed in centimeters/unit time and get creative with how you display the value. For instance, if the speed is 1873 centimeters/second, and you want to see that in meters/second, convert the value to a string ("1873") and print all but the last two characters, then a dot, then the last two characters, so you get "18.73". No floating point arithmetic involved.

PaulS,

I understand a bit more now. So with a update rate of say once every 15 seconds up to maybe a max of about once every 5 - 7.5 seconds a float would not be out of the question to use. I guess I'll try the float option first and if it yields bad results then I'll give it a shot being a bit more creative.

in this instance I'm only accumulating mileage counter and at a max speed of 120mph that means I would have to update once every 7.5 seconds or so. I'll give it a shot see what happens.

Generaly speaking, don't use floats for things that are not approximate values.

If your odo counts quarter miles, then store an whole number of quarter miles. I always suggest suffixing your variables to indicate the unit you are using: ctQMi, sumQMi, totalQMi and so on.