- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I want to save some data using EEPROM component. But I don't know how to do it since EEPROM only except uint8 data type.
But I want to save data which are of String data type. For example, if I want to save this line on EEPROM from my code: {\"ADC\": %.0f , \"LM35\": %.1f , \"TC74\": %.0f , \"SPI\": %.1f }\r\n", average, temp, I2Cavg, SPIavg);. How can I actually do this? I am attaching my code. What I am trying to do is save all the data on EEPROM
which I am showing via UART and in the end how can I download all the data from EEPROM as a text document on my PC.
Best Regards,
Nasir Ahmed
Solved! Go to Solution.
- Tags:
- psoc5lp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
May be this is pedantic, but I think that you need to aware of a couple of things about EEPROM.
(1) EEPROM has a limited durability
(2) EEPROM is not very big
(1) According to the datasheet the read/write cycle is 1,000,000.
It may sound as a big number, we have 86,400 seconds a day.
If you save data twice a second it make the number 172,800.
Now if I calculate 1,000,000 / 172,800 = 5.787 (days)
So if you keep the program running, the EEPROM in the PSoC 5LP will not last a week.
(2) In case of CY8C5888LTI-LP097, the size of EEPROM is 2048 bytes.
With my test program, with fixed data, the length of the string was 34 bytes
(35 bytes with null)
If you keep appending the data next to the previous data in the EEPROM,
2048 / 35 = 58.51429
So again, if you append 2 strings a second, within 30 second the EEPROM will be full.
Having written that I modified your program as follows
(1) Save a string once only when SendSingleByte = True.
(2) With 'R' or 'r' typed it will read back the string from EEPROM and send it to the UART.
So the TeraTerm log looks like below
Note: In this log, I let it run for 2sec with 's' then stopped it with 'x'
Then I typed 'c' the fifth line,
Then I typed 'r' the sixth line.
Although I talked with the size of data, still I saved/restored the string for this example.
But saving and restoring only the data and construct the string is more recommended just like /odissey1-san suggested.
So I attached
(1) modified project of yours nasirPSoC5Serial_200603
(2) my EEPROM test program which I wrote a while ago to show you how to write/read raw data.
Best Regards,
3-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
You said "everyone", then why there was my name? (lol)
Anyway, I could not find source file in your attached project,
I tried to write a simple sample with CY8CKIT-059.
Note: uint8_t and char is usually exhangeable if you are sure about the contents.
main.c
=================
#include "project.h"
#include "stdio.h"
#include "string.h"
#include "tty_utils.h"
#define DATA_BUF_LEN 256
char *format = "{\"ADC\": %.0f , \"LM35\": %.1f , \"TC74\": %.0f , \"SPI\": %.1f }\r\n" ;
char data_buf[DATA_BUF_LEN+1] ;
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
tty_init() ;
EEPROM_Start() ;
EEPROM_UpdateTemperature() ;
}
int main(void)
{
int len, i ;
int row_no = 0 ;
float average = 1.2 ;
float temp = 2.3 ;
int I2Cavg = 3 ;
float SPIavg = 4.5 ;
init_hardware() ;
splash("5LP EEPROM TEST") ;
snprintf(str, STR_BUF_LEN, "EEPROM Size = %d Bytes\n", CYDEV_EE_SIZE) ;
print(str) ;
/* read saved data */
i = 0 ;
data_buf = EEPROM_ReadByte(i) ;
do {
i++ ;
data_buf = EEPROM_ReadByte(i) ;
} while(data_buf != 0) ;
if (data_buf[0] != 0) {
print(data_buf) ;
}
len = snprintf(data_buf, DATA_BUF_LEN, format, average, temp, I2Cavg, SPIavg) ;
#if 1
EEPROM_Write((uint8_t *)data_buf, row_no) ;
#else
for (i = 0 ; i < len ; i++ ) {
EEPROM_WriteByte((uint8_t)data_buf, i) ;
}
EEPROM_WriteByte(0, i) ;
#endif
for(;;)
{
/* Place your application code here. */
}
}
=================
The Tera Term log
Note: This is screen is 2nd run or later, in the first run, since there is no content in the EEPROM,
the string was not written on the screen.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
All the time I asked a question here, I got correct answer from you and I that's why I thought to tag you. (lol)
By the way as I tried to run your code on PUTTY, I got this:
Why is that? And you didn't use the variable 'len'.
I didn't attach the Project correctly. Now I am attaching the correct ZIP folder.
Best Regards,
NA
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
I'm very sorry, it was my bad.
In the main.c where #if 1 was located, at first it was #if 0 like below
=======================
#if 0
EEPROM_Write((uint8_t *)data_buf, row_no) ;
#else
for (i = 0 ; i < len ; i++ ) {
EEPROM_WriteByte((uint8_t)data_buf, i) ;
}
EEPROM_WriteByte(0, i) ;
#endif
=======================
So that I was using len to count the number of bytes to write to the EEPROM.
And for the last thing I changed it to use EEPROM_Write(), which writes only 16 bytes,
but somehow I thought it was 256 bytes.
Anyway, with this configuration, it should work.
But please check if len does not exceed the CYDEV_EE_SIZE, which is the size of the EEPROM.
Best Regards,
2-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
May be this is pedantic, but I think that you need to aware of a couple of things about EEPROM.
(1) EEPROM has a limited durability
(2) EEPROM is not very big
(1) According to the datasheet the read/write cycle is 1,000,000.
It may sound as a big number, we have 86,400 seconds a day.
If you save data twice a second it make the number 172,800.
Now if I calculate 1,000,000 / 172,800 = 5.787 (days)
So if you keep the program running, the EEPROM in the PSoC 5LP will not last a week.
(2) In case of CY8C5888LTI-LP097, the size of EEPROM is 2048 bytes.
With my test program, with fixed data, the length of the string was 34 bytes
(35 bytes with null)
If you keep appending the data next to the previous data in the EEPROM,
2048 / 35 = 58.51429
So again, if you append 2 strings a second, within 30 second the EEPROM will be full.
Having written that I modified your program as follows
(1) Save a string once only when SendSingleByte = True.
(2) With 'R' or 'r' typed it will read back the string from EEPROM and send it to the UART.
So the TeraTerm log looks like below
Note: In this log, I let it run for 2sec with 's' then stopped it with 'x'
Then I typed 'c' the fifth line,
Then I typed 'r' the sixth line.
Although I talked with the size of data, still I saved/restored the string for this example.
But saving and restoring only the data and construct the string is more recommended just like /odissey1-san suggested.
So I attached
(1) modified project of yours nasirPSoC5Serial_200603
(2) my EEPROM test program which I wrote a while ago to show you how to write/read raw data.
Best Regards,
3-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear MoTa_728816,
thanks a lot for all that information.
But what I want to do is save all the data of multiple lines while 's' is pressed. I know it will be critical with the memory of the EEPROM as you mentioned and that's why I am thinking of increasing the period value of the Timer. For example, setting the Period value to 900 seconds. And if 'r' or 'R' is pressed, it will show all the data of multiple lines that were saved. Will it be possible?
BR
nasir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
If you use Em_EEPROM, may be you can add some more lines.
But 900 sec x 2 line = 1800 lines? might be very difficult.
Practically, I would recommend you to use the serial terminal program on PC,
such as Tera Term which can store tons of line without much penalty.
Best Regards,
3-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san
After posting my previous response,
I noticed that you were saying one line/900 sec,
then the story will be very different.
Meantime, if you use Em_EEPROM instead of EEPROM,
you should get much more space for the data.
Best Regards,
3-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
First of all let me say(write) that I strongly recommend you to store and restore only the value then reconstruct the data in the program.
And to prolong the life of Flash, keep the write cycle as few as possible,
so having long interval between measure/save will be nice.
Having written, that following is my trial of today.
I changed EEPROM to Em_EEPROM.
And I allocated 64KB for Em_EEPROM.
After starting the program, I pushed 's' and let it run for a few seconds
Then I typed 'x' and 'r'
Best Regards,
4-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear MoTa_728816,
Thanks it works. However I tried the same thing on my another project where I also messaure the temperature with other sensors and save those data on Em_EEPROM, it didn't work properley. Don't understand why, cause everything remained quite the same. When I press 'r' after 'x',
it only shows the first 4 lines of data saved like this:
Why is that happening? My project is attached.
Best Regards,
Nasir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
I wrote
> And I allocated 64KB for Em_EEPROM.
I set the size of Em_EEPROM 65536
But you used the default size, which is 256 bytes
So, I think that this is the root cause.
And I found my bug, too.
In the following function, I should have checked the address before write
====================
void save_str_to_eeprom(char *str, uint len)
{
/* write data from address 0 */
Em_EEPROM_Write(em_eeprom_write_address, str, len) ;
em_eeprom_write_address += len ;
}
====================
So I was thinking that I did like below
====================
void save_str_to_eeprom(char *str, uint len)
{
if ((em_eeprom_write_address+len) >= Em_EEPROM_PHYSICAL_SIZE) {
print("Write: Em_EEPROM size exceeded!\n\r") ;
return ;
}
/* write data from address 0 */
Em_EEPROM_Write(em_eeprom_write_address, str, len) ;
em_eeprom_write_address += len ;
}
====================
And that line was in the get_str_from_eeprom() orz
Anyway, I think that we have done enough for this thread.
Please create a new thread/discussion if you have more question(s).
Best Regards,
4-Jun-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
NaAh,
I believe that correct way would be to store individual values in the EEPROM, and format the output only when sending data to PC. For that you can use custom component, which stores any data types:
myEEPROM: component to save/recall application settings in EEPROM between power offs
/odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have the Kit: CY8C5888LTI-LP097. So your component will not work on my PSoC.
NA