|
|
View previous topic :: View next topic |
Author |
Message |
samus111
Joined: 28 Aug 2014 Posts: 29 Location: Colombia
|
EEPROM read/write problem |
Posted: Wed Sep 10, 2014 9:20 am |
|
|
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
|
|
Posted: Wed Sep 10, 2014 10:12 am |
|
|
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
|
|
Posted: Wed Sep 10, 2014 11:09 am |
|
|
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: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Sep 10, 2014 2:01 pm |
|
|
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
|
|
Posted: Wed Sep 10, 2014 2:23 pm |
|
|
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
|
|
Posted: Wed Sep 10, 2014 3:04 pm |
|
|
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: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Sep 10, 2014 3:20 pm |
|
|
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
|
|
Posted: Wed Sep 10, 2014 3:43 pm |
|
|
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
|
|
Posted: Wed Sep 10, 2014 3:48 pm |
|
|
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: 303
|
|
Posted: Wed Sep 10, 2014 3:48 pm |
|
|
temp[0] is the first byte, temp[31] is the 32nd byte. |
|
|
samus111
Joined: 28 Aug 2014 Posts: 29 Location: Colombia
|
|
Posted: Wed Sep 10, 2014 3:58 pm |
|
|
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
|
|
Posted: Wed Sep 10, 2014 5:50 pm |
|
|
Hi,
In general that is not true, you are just wildly guessing to explain the observed result 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: 1635 Location: Perth, Australia
|
|
Posted: Wed Sep 10, 2014 7:14 pm |
|
|
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: 1635 Location: Perth, Australia
|
|
Posted: Wed Sep 10, 2014 7:22 pm |
|
|
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: 19539
|
|
Posted: Thu Sep 11, 2014 2:01 am |
|
|
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..... |
|
|
|
|
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
|