7 years, 5 months ago.

i want to assign int value saved in sd to a variable in code? please help

The value of water come 50 but the value of total is 2000.

include the mbed library with this snippet

#include "mbed.h"
#include "SDFileSystem.h"
DigitalOut myled(LED1);
SDFileSystem sd(p5, p6, p7, p8, "sd");
int total = 2000;
int main()
{

        //Mount the filesystem
        sd.mount();


        printf("\nWriting to SD card...");
        FILE *fp = fopen("/sd/sdtest.txt", "w");
        if (fp != NULL) {
            fprintf(fp, "%d", total);
            fclose(fp);
            printf("success!\n");
        } else {
            printf("failed!\n");
        }

//Perform a read test
        printf("Reading from SD card...");
        fp = fopen("/sd/sdtest.txt", "r");
        if (fp != NULL) {
            char c = fgetc(fp);
            int water = c;
            if (c == 'W')
                printf("success= %d",total+2);
            else
                printf("incorrect char (%c)!\n", c);
            fclose(fp);
            
        FILE *fp = fopen("/sd/sdtest1.txt", "w");
        if (fp != NULL)
            fprintf(fp, "totalizer = %d", water);
            fclose(fp);
            printf("success!\n");
        } else {
            printf("failed!\n");
        }
        while(1) {
            myled = 1;
            wait(0.2);
            myled = 0;
            wait(0.2);
        }
    }

Question relating to:

Rapid Prototyping for general microcontroller applications, Ethernet, USB and 32-bit ARM® Cortex™-M3 based designs

1 Answer

7 years, 5 months ago.

Jay,

First, I think some of the brackets around your if statements are misplaced. Line 26 and line 36 to start.

Then, anytime you fprintf to a file, you are saving the decimal number encoded as ascii text. When you read it back you are reading back ascii characters again. You have to first read the ascii characters in the file, break them into tokens, and then convert the tokens back into integers.

Assuming your file has more than one value, you'll need a way to separate values. I used a newline character. Assumption is there is one integer per line.

I think you need to call sd.unmount(), when you are done with the card to free it.

On my board the led won't actually blink because it shares a pin with the sd card.

This is mostly working for me. Writes integer to disk, reads ascii string back, converts into integer, writes it to a new file.

#include "mbed.h"
#include "SDFileSystem.h"

DigitalOut myled(LED1);
SDFileSystem sd(D11, D12, D13, D10, "sd");

const int total = 2000;
int result = 0;

/* Main */
int main() {

	/* Mount the filesystem */
	sd.mount();

	printf("\r\n\r\nWriting to SD card...\r\n");

	/* Open for Writing: w = write from beginning */
	FILE *fp = fopen("/sd/sdtest.txt", "w");

	if (fp != NULL) {
		fprintf(fp, "%d\r\n", total);
		fclose(fp);
		printf("write: success!\r\n");
	}
	else {
		printf("write: failed!\r\n");
	}

	/* Perform a read test */
	printf("Reading from SD card...\r\n");

	fp = fopen("/sd/sdtest.txt", "r");

	if (fp != NULL) {
		char buffer[10] = {0};
		char c = {0};
		char *token;
		int i = 0;

		/* Read Chars Until End of Line */
		while ((c != '\n') && (i < 10)) {
			c = fgetc(fp);
			buffer[i] = c;
			i++;
		}

		/* Get Token: Probably not needed, but Useful for More Numbers */
		token = strtok(buffer, "\n");

		/* String to Int Function */
		result = atoi(token);

		printf("read success: buffer = %s  result = %d\r\n",buffer,result);

		fclose(fp);
	}
	else {
		printf("read: failed!\r\n");
	}

	/* Write Read Value Back to SD */
	FILE *fp1 = fopen("/sd/sdtest1.txt", "w");

	if (fp1 != NULL) {
		fprintf(fp1, "totalizer = %d\r\n", result);
		fclose(fp1);
		printf("write back: success!\r\n");
	}
	else {
		printf("write back: failed!\r\n");
	}

	/* Free the SD Card */
	sd.unmount();

        /* Spin */
	while(1) {
		myled = !myled;
		wait(0.2);
	}
}

Graham

Accepted Answer

will this work for a float value also?

posted by jayendra mishra 02 Nov 2016

Not like this. First on line 22 you have to use %.2f. or similar to write a float number to text output. Then interpreting the token, like 52, atoi(), is looking for an integer and will return an integer. I think the function, atof(), will return a double precision float from the token. Just remember the variable result needs to be type double, not type float. I don't have time to actually try this right now.

https://www.tutorialspoint.com/c_standard_library/c_function_atof.htm

posted by Graham S. 03 Nov 2016

Hey Graham, I am trying to learn to use EEprom memory, but having a hard time. I want to put an integer value and use bit shifting for a float value. the following code provides me with int values from 0 to 255 only. Can you please guide me. I wnt to store and read a float value.

float Q = 1122.53
 //wp = 0; // disable write protect
  lcd.clear();
                lcd.setPosition(0, 0);
    lcd.printf("Writing bytes 0-16\n");
    i2c.start();
    char data[3];
    for(int i=0; i<16; i++) {
        data[0] = 0;     // MSB address
        data[1] = i;     // LSB address
        data[2] = i * 3; // data
        if(i2c.write(0xA0, data, 3)) {
            error("Write failed\n");
        }
        while(i2c.write(0xA0, NULL, 0)); // wait to complete
    }
 
    data[0] = 0;       // MSB address
    data[1] = 255;     // LSB address
    data[2] = Q;     // data
    if(i2c.write(0xA0, data, 3)) {
        error("Write failed\n");
    }
    while(i2c.write(0xA0, NULL, 0)); // wait to complete
 lcd.clear();
                lcd.setPosition(0, 0);
    lcd.printf("Setting read pointer to 0\n");
 
    data[0] = 0;                   // MSB address
    data[1] = 0;                   // LSB address
    if(i2c.write(0xA0, data, 2)) { // send address, but no data
        error("Write failed\n");
    }
 
    printf("Reading back data bytes 0-16\n");
    
    char response[1];
    for(int i=0; i<256; i++) {
        if(i2c.read(0xA0, response, 1)) {
            error("Read failed\n");
        }
        i2c.stop();
        lcd.clear();
                lcd.setPosition(0, 0);
        lcd.printf("address  %1.2f\n", response[0]);
    }
    
    wait(5);
    
 }
posted by jayendra mishra 22 Mar 2017

Jay,

If I understand your issue, you want to have a float number but be able to access individual bytes so you can send them to the EEPROM. You can do that by using union.

typedef struct bytes_32 {
    uint8_t b0;
    uint8_t b1;
    uint8_t b2;
    uint8_t b3;
} bytes_32;
 
typedef union {
    float data;
    bytes_32 bytes;
} float_packed;

float_packed Q;
char a,b,c,d;
	
/* Use Q as float */
Q.data = 112.53;	
	
/* Access Q as bytes */
a = Q.bytes.b3;
b = Q.bytes.b2;
c = Q.bytes.b1;
d = Q.bytes.b0;
posted by Graham S. 23 Mar 2017