CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

EEPROM read/write problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
samus111



Joined: 28 Aug 2014
Posts: 29
Location: Colombia

View user's profile Send private message AIM Address

EEPROM read/write problem
PostPosted: Wed Sep 10, 2014 9:20 am     Reply with quote

Good day.
I am working on a project that consists to transmit a GPS coordinate through the Iridium module 9603 to the Iridium network and later, receive it in a email account (the module makes the transmission to the network, I only have to give the word to it).

The communication is via UART. First, I obtain a GPS coordinate by a L80 GPS module. Next, I store that data in the EEPROM. After this, I wait a minute to obtain other coordinate, and so on until I store 7 coordinates. Once I get them, I power on the Iridium module, and try to write them in its buffer for then, send them to the network. It sounds easy, but the problem is that, when I write them, the Iridium module only receives the firsts 4 coordinates. The other three arrive to the Iridium module empty.

I am using a 16F688 which has 256 bytes in its EEPROM, and the Iridium module has 340 bytes of buffer. I don't know what is the problem. The truth is, that if I try to send only 5 coordinates or less, the PIC writes them all well. But if I try with 6 or more, the PIC only sends the firsts 4, and the others arrive to the buffer empty. Here is the code, sorry for my english, is not my native language, thanks.

global vars used
Code:

char       temp[32]="";    //temporal string, It will hold the last coordinate obtained with the GPS
                           //module to be stored in the EERPOM
                           //and later will receive the stored coordinate to be printed.
int        F=1;            //waiting time, in this case 1 minute. 
signed int rme=1;          //reports in memory, number of GPS coordinates that are stored.
int        R=7             //maximum number of reports in memory that will be stored.


MAIN FUNCTION PROGRAM
Code:

for(; ; )

MGPS();                   //module GPS function, It will obtain the GPS coordinate and that will be stored in the "temp" string.

i=0;
for (rmex=31*rme-31;rmex<=31*rme;rmex++){  //Loop that will store the present coordinate (31 bytes) in the EEPROM
//adding 31 memory address positions each time a new coordinate going to be stored.
write_eeprom(rmex,temp[i]);               
i++;};

if(rme>=R) {                              // if the reports stored in memory is equal to the maximun reports We want
MI();                                     // power on the Iridum module and send the reports stored in the EEPROM.
rme=1;};                                  // restart the counter
rme++;                                   
       for(Fx=0;Fx<F;Fx++) {              // wait a minute
       delay_ms(60000);};                 
};

Code:

MI() function part
/////////////////////////////////////////////////////////////////////////////////////
 while(rme>1){                           
 i=31;
     for(sm=rme*31;sm>=rme*31-31;sm--){   //the same process like the writing, but this time, starting from the last EEPROM memory  position to the first.
     temp[i]=read_eeprom(sm);
     i--;};
     temp[31]="";                         //there is a bug in the final of the printed word if I don't clean this byte (I don't know why, maybe someone can help me here)
     printf("%s/",temp);
 rme--;};

 i=31;                                    //the last coordinate must to be printed with a "\r" to communicate to the module that the message is complete
 for(sm=31;sm>=0;sm--){
 temp[i]=read_eeprom(sm);
 i--;};
 i=0;
 temp[31]="";
 printf("%s \r",temp);
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 10:12 am     Reply with quote

Hi,

A number of comments come to mind:

1. You already have a thread on this same basic project. It is not considered good forum etiquette to start multiple forum threads on the same basic project.

2. Learn to use the Code button when posting your actual code. When you do this, the formatting (if any!) is maintained, and the code is much easier to read! [Fixed - Forum Moderator]

3. Post your actual code by cutting and pasting, don't type it in. As posted, there are a number of omissions in your code that suggest it's not a cut-n-paste. Eg. a missing '{' on your For loop.

4. Your code is mind-numbingly hard to read. Your variable names are really horrible, and your use of 'cute' techniques like the use of an offset in the For loop to stuff 7 sets of characters sequentially into memory space is really hard to understand, and really hard to troubleshoot. I'd do this in two loops if it were me. Much easier to understand and maintain.

5. I would avoid using EEPROM for this. EEPROM is life limited in terms of writes, and it's generally not a good idea to use this type of memory for regularly occurring operations like this. Eventually, you'll wear out the memory. Ram, if available, is a better choice, or even some type of external memory, like FRAM, is better. EEPROM writes are also really slow!

6. Your code lacks a lot of good commenting, but I assume that you are using 'Printf' to send data to the modem? Are you aware that the '%s' (String) variable type requires a Null terminator to work properly? This is probably a large part of your problem. Do you actually know for sure what is being received by the modem? You should send the same data to a diagnostic serial port to see what is actually being sent/received. It would also be a good idea to specify a serial 'Stream' name to make your code more clear.

John
samus111



Joined: 28 Aug 2014
Posts: 29
Location: Colombia

View user's profile Send private message AIM Address

PostPosted: Wed Sep 10, 2014 11:09 am     Reply with quote

Hi John.
1. Of course, You are right, I started other subject the last time, but I am confused, I remember that you told me to open a thread according to the subject issue, well this time the problem is with the EEPROM, that's why I did not post this problem through my last thread. I am going to erase my last thread.
2.3. I will take it in mind, thanks.
4. Well, I only try to use the less code lines as possible, my ROM is limited, and the code is very large (I have more than 70% of memory ROM in use, and the program still is not finished), but I will take it in mind for the next time that I put my code here.
5. The problem is that the project is based on a minimal size possible (1cmx1cm), that's why I am using a 14 pins PIC, even, I am going to try with 12F1840 because it has only 8 pins and also supports UART and EEPROM. For now, I have been able to make the communication only using: a SMT transistor for coupling the modules, a SMT 16F688 that fit perfectly in the backside of the GPS module, a supercap that fits at a side of the iridium module with a LiPo battery of 1300mAh. The RAM memory will be useful later to store more coordinates, in total, I need to send 10 stored reports, 8 using the EEPROM (31 bytes each coordinate x 8=248bytes / 256 bytes 16F688's EEPROM ) and the RAM memory will store the other two; but this one it is very limited, with only 3 strings of 31bytes each one, the RAM turns to more than 75% in use. thats why I need to use the internal EEPROM; use other component is not an option for now.
6. Of course that I do; I am using a interface to look everything is happening between the three components, and if you can see, my string temp has 32 size bytes, and I always write untill the 31, my program header is the next one
Code:
#include <16f688.h>
#include <string.h>
#include <stdlib.h>   
#use delay (internal=4000000)
#fuses noput, intrc, nowdt
#use R232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C4,RCV=PIN_C5,STREAM=GPS, ERRORS, TIMEOUT=2500)

I hope you can help me, the last time you solved my problem, I just added the ERRORS sentence inside the RS232 command, and everything starts to work perfectly Thanks.
temtronic



Joined: 01 Jul 2010
Posts: 9173
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 2:01 pm     Reply with quote

re... The problem is that the project is based on a minimal size possible (1cmx1cm)

WHO decided THAT condition ????? Obviously NOT someone who has ANY idea about how a project 'grows' either in features or 'one-more-pin-itis' !!

With almost 40 years in this 'game' I have never understood the 'make-it-small' mentality. I use 'big' PICs with LOTs of memory,peripherals and pins. It always happens...3 days late 'they' decide , oh we need this feature or gee and LED would be nice...

OK 1cm x 1cm , what about the other dimension ??? The 'classic' stacking RAM on RAM,RAM on EPROM comes to mind for early computers.

Smaller is NOT always better.

just food for thought..

Jay
samus111



Joined: 28 Aug 2014
Posts: 29
Location: Colombia

View user's profile Send private message AIM Address

PostPosted: Wed Sep 10, 2014 2:23 pm     Reply with quote

one-more-pin-itis...jejeje it sounds funny, the focus is that the project is oriented to the security, and not only the device must to be small, also must to be imperceptible for anyone, 1mm less or 1mm more can be crucial; I think, if there is not other way, I will have to use more elements, but with a critical eye, I can see that is possible to build this device in the way I am working, even, the device works well, the unique issue is that is having problems to store more than 4 coordinates. I wonder if the problem is for the way I am printing (but I also ask myself why with 4 coordinates works well) or if the problem is something that I am not taking in mind (maybe a bank memory, overflow memory, array pointer or something that I do not know yet). By the way, how is the correct way to print the string, I am storing the word in a string with 32 bytes, of which 31 bytes has a character, but the byte 32 I never make nothing with it, I know that is called the null byte, and it will hold the checksum data or something so, but, how is the right way to configure this byte, It must be clean(" ")?It must be on zero("0")? or what I must to do? thanks.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 3:04 pm     Reply with quote

Hi,

Here is how I generally null terminate a string:

Code:

NMEA_STR[NMEAIndex] = '\0';


I made a test program that used ="" to do the same thing and it seemed to work, but I didn't test it extensively.

John
temtronic



Joined: 01 Jul 2010
Posts: 9173
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 3:20 pm     Reply with quote

hmm.. "it seemed to work"...

yeah, until the maybe next compiler version ?

I prefer to HARD CODE stuff like that, same as programming fuses. Never rely on the 'default' values....somehow 'they' might not be the ones that they used to be.

It also gives you a 'hard copy' comment as to what's going on. 3 dayze or 3 months from now you can see what you did and why, relying on 'hidden' or 'default' features or settings WILL come back to cause no end of grief.

jay
samus111



Joined: 28 Aug 2014
Posts: 29
Location: Colombia

View user's profile Send private message AIM Address

PostPosted: Wed Sep 10, 2014 3:43 pm     Reply with quote

well in my case I would try with the assignment:
temp[32]='\0';
I believe is right, the 32 byte is the last of the temp string; but when I try to make this, CCS gives me the next warning: subscript out of range.
I think the last byte can not be modified or something so, however, I set this assignment to the byte 31, and the program runs well, but there is no change in the words that the device writes to the Iridium module buffer :(.

here is a part of the log file from the serial port monitoring.

$GPRMC,210948.437,V,,,,,0.14,0.00,100914,,,N*43
$GPVTG,0.00,T,,M,0.14,N,0.26,K,N*33
$GPGGA,210948.437,,,,,0,3,,,M,,M,,*4D
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,2,1,07,05,60,315,31,26,40,172,24,12,39,287,33,17,33,117,*7C
$GPGSV,2,2,07,10,28,022,,15,16,204,,24,04,232,*41
$GPGLL,,,,,210948.437,V,N*7C
$GPRMC,210949.437,A,0&&&.&&&&,N,0&&&&.&&&&,W,0.40,0.00,100914,,,A*7C
$GPVTG,0.00,T,,M,0.40,N,0.74,K,A*3A
$GPGGA,210949.437,0&&&.&&&&,N,0&&&&.&&&&,W,1,4,1.50,2614.4,M,3.1,M,,*40
$GPGSA,A,3,26,05,12,10,,,,,,,,,1.79,1.50,0.97*04
$GPGSV,2,1,08,05,60,315,30,26,40,172,27,12,39,287,32,17,33,117,*70
$GPGSV,2,2,08,10,28,022,26,33,23,092,,15,16,204,,24,04,232,*70
$GPGLL,0&&&.&&&&,N,0&&&&.&&&&,W,210949.437,A,A*42
$GPRMC,210950.437,A,0&&&.&&&&,N,0&&&&.&&&&,W,0.64,84.55,10
AT

OK
AT+SBDWT

READY
/ /21,10,0&&&.&&&&,N,0&&&&.&&&&,W /21,10,0&&&.&&&&,N,0&&&&.&&&&,W /21,10,0&&&.&&&&,N,0&&&&.&&&&,W /21,10,0&&&.&&&&,N,0&&&&.&&&&,W
0

OK
AT+CSQ

+CSQ:0

OK

well, the script system of this website do not allow to show spaces between characters (or so appear to be), but the first two / that appear before the 4 coordinates have between them exactly 31 spaces (seems like the PIC tries to write the data, but when the printf command takes this slots, are empty)
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 3:48 pm     Reply with quote

Hi,

Basic 'C' programming. A declaration of 'char Temp[32];' means that 32 elements in memory are reserved for 'Temp'. These elements are referenced as Temp[0] thru Temp[31], for a total of 32. To solve this immediate problem you could:

1. Make Temp[31] = the Null character
2. Increase the size of the string array, ie. Char Temp[33];

John
gaugeguy



Joined: 05 Apr 2011
Posts: 296

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 3:48 pm     Reply with quote

temp[0] is the first byte, temp[31] is the 32nd byte.
samus111



Joined: 28 Aug 2014
Posts: 29
Location: Colombia

View user's profile Send private message AIM Address

PostPosted: Wed Sep 10, 2014 3:58 pm     Reply with quote

Of course I made it in that way, I assigned
temp[31]='\0';
just before to print, but the result is the log that I attached. :( I think the EEPROM memory does not support more than certain number of bytes stored no matter if the memory is not full.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 5:50 pm     Reply with quote

Hi,

In general that is not true, you are just wildly guessing to explain the observed result Shocked You need to explain more fully what is not working correctly, or you need to do more troubleshooting, or both.....

John
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Sep 10, 2014 7:14 pm     Reply with quote

samus111 wrote:
Hi John.
4. Well, I only try to use the less code lines as possible, my ROM is limited, and the code is very large (I have more than 70% of memory ROM in use, and the program still is not finished),


In the example code you have posted, you can reduce the code size significantly by not using printf. Printf is a powerful format print function but includes a lot of overhead unnecessary for this application.

Here is a simple example:

Code:

   // call this with the null terminated string to be printed
   void MyPrintString(char *ptr)
    {
   
         while (*ptr)
             putc(*ptr++);
     }

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Sep 10, 2014 7:22 pm     Reply with quote

samus111 wrote:
I think the EEPROM memory does not support more than certain number of bytes stored no matter if the memory is not full.


As pointed out already - this is not correct.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19365

View user's profile Send private message

PostPosted: Thu Sep 11, 2014 2:01 am     Reply with quote

If you need to go really small, then just get a core.
Bond this directly to the board.

I've built devices significantly smaller than this, and used much larger PIC's.

Talk to somebody who is a specialist in such things. Your approach is going the wrong way. You need to start with the external stuff. How small each part of this can be made, then 'work back' towards the processor, miniaturising at each step. You will undoubtedly find that simple things like power supply capacitors, will be larger than your processor and all it's connections.....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group