Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

help please memory problem

Status
Not open for further replies.

Dami

New Member
hey guys im designing an ecg system for my project using a PIC18F4620, basically i need to sample in 100 data points from the analogue input and store them in an array. I will then manipulate this array to get my results.

Now I can use the ADC but the problem I have now is storing 100 datapoints (of type float because they have to be accurate to 2 decimal places). The MPLAB compiler would not let me and gives an error 1300.

100 datapoints would take 400 bytes of memory, the RAM has 3800 bytes so I do not know why I cannot do this.

Any suggestions guys or tips would be much appriciated.
 
What language are you using , C or assembler ?
(if C, what compiler brand ? )

Also, the ADC returns 10 bit 'integer' values, why are you storing them as floating point values. Are they already converted so something before you store them?...
 
Dami said:
hey guys im designing an ecg system for my project using a PIC18F4620, basically i need to sample in 100 data points from the analogue input and store them in an array. I will then manipulate this array to get my results.

Now I can use the ADC but the problem I have now is storing 100 datapoints (of type float because they have to be accurate to 2 decimal places). The MPLAB compiler would not let me and gives an error 1300.

100 datapoints would take 400 bytes of memory, the RAM has 3800 bytes so I do not know why I cannot do this.

Any suggestions guys or tips would be much appriciated.

For a start don't use 'float', there's only very rarely any need to do so (and you certainly have no need!) - floating point is very slow, takes lots of program space, and uses lots of variable space - it's also inaccurate. Use integers - for a start the A2D readings are integer anyway!. Integers are many times faster, use much less space, and are 100% accurate (unless you do something stupid!) - assuming you want to display to two decimal places?, do so in your display routine from the integer result.
 
ok I am not using the ADC now.

Right now I have the data points on my computer. I am not using the ADC at the moment. I am just creating an array in the C program with the data points I already have. I am using MPLABC18.

e.g float array1[]={1.34,1.43,1.21,1.17,1.06]}.

this is a small array actually i have 300 data points. I am worried if I use -int- I will not get the precision in the decimal places to do various arrithmatic so the above data points would become

int array1[]={1,1,1,1,1} instead of float array1[]={1.34,1.43,1.21,1.17,1.06]}.

hope I have explained my problem clearly. Maybe my concept of int is wrong it just that when I used int and debugged I did not see any decimal points in my array.
 
You are not getting the point here :!:
Imagine ADC will give you a value of 250 decimal... (ADC is NOT producing float values, only int from 0-1023) so your array would be:
int array[]{250,256,458,123}... That'a all.
 
I understand what you are saying


My input is between +1V and -1V so this range would be converted to a value between 0 to 1023 by the ADC. Now in the array i need to represent the numbers as they were in the input signal i.e between (+1V and -1V) by multiplying by 2/1023. The array has to be in voltages for me to continue.
 
Dami said:
I understand what you are saying


My input is between +1V and -1V so this range would be converted to a value between 0 to 1023 by the ADC. Now in the array i need to represent the numbers as they were in the input signal i.e between (+1V and -1V) by multiplying by 2/1023. The array has to be in voltages for me to continue.
Finally we know what you want to achieve...
How did you input the -1V to PIC? Post us your schematic.
 
I have the data in a text file so I am going to create a wav file and take the output from the PC soundcard as the input to the ADC. The reason why I need the array in voltages is to do digital filtering , and signal analysis which I have already implemented in Matlab.
 
are you doing the signal processing on the PIC, or exporting the values to a computer to let MATLAB do the processing?

if you are trying to implement digital signal processing on a PIC, using floating-point arithmetic, perhaps you should reconsider. or perhaps look at the dsPIC series, as they are designed for digital signal processing. regular PICs are really not set up for doing floating-point arithmetic like that. You can probably do it with a C compiler (or some pre-written assembly routines) that handle the floating point part, however in any case it would be extremely inefficient (slow).

if you are only exporting them to the computer, then there shouldn't be any need to convert them to floating point values, that's something much more suited for MATLAB to do with some simple code.
 
Dami said:
I applied +1 and -1 to AN3 and AN2 of the PIC which defines the range for the ADC

Try reading the datasheets, +1V is below the permitted range for VRef+, and -1V is also too low for VRef-. It's all explained in the DC characteristics at the back of the datasheets. You won't be getting anything like accurate readings like this, you should scale the inputs using an opamp, and use references from 0V to a 2.5V precision reference source (or even the 5V supply would be more accurate than what you've got).

You're also not thinking clearly about the figures themselves, you suggested:

int array1[]={1,1,1,1,1} instead of float array1[]={1.34,1.43,1.21,1.17,1.06]}.

I would write that as:

int array1[]={134,143,121,117,106} instead of float array1[]={1.34,1.43,1.21,1.17,1.06]}.

This keeps the numbers integer and accurate (and MUCH faster - probably 100 times faster?).

A quick multiplication check with Windows calculator gives:

2.8755302004

Using integers gives:

28755302004

All you need to do is insert the decimal point in the correct place to give the final exact result. The floating version, while fully accurate (in this example) using Windows calculator, most probably won't be in practice.

BTW, I used multiply to demonstrate the inaccuracies of floating point - which rather failed as Windows calculator performed better than I thought :lol:
 
Dami said:
I applied +1 and -1 to AN3 and AN2 of the PIC which defines the range for the ADC
I though you will use this, BUT this is not OK. You won't achieve any good resolution, you may even damage the PIC... Try to convert that +-1V signal to 0-2V (with Vref 2.5V and you are safe).
Just like Nigel supposed :D
 
Like the others said:
- You need a circuit that shifts your -1V <-> 1V value to 0 - 2V, then you can calculate the real value in software.
- Like Nigel said, it's better to use an integer array and fill in the decimal point at then end in the display or output routine.
- MPLAB C18 by default makes 1 standard section for uninitialized data per file, named udata_filename. The maximum size of 1 section is 256 bytes.
To get around this you should:
- eighter split up your array in multiple pieces, eighter of them in a separate udata section. (read C18 documentation about #pragma directives on how to do this)
- or modify your project's linker script to force the linker to use 1 large ram section (spread across banks - only accessible trough a pointer -keep that in mind!) (also documented in the c18 manual)
- or dynamically allocate the memory required, but in my personal opinion, dynamic memory allocation on small devices is pretty pointless.

as a last note, i see in the above example you only use 2 digits behind the comma. In this case you could even use an 'char array'. Since a char is byte and can go from
-127 to +127 it can hold your data

Use -100 to represent -1.00 up to 100 to represent 1.00. This would cut your array size in 2 ! Also, converting the ADC's 10bit result to this format can be handled very simple and fast.
 
Thanks guys will try this.

I was also thinking to write in the data from the ADC into the EEPROM and then take 1 integer at a time into my program. What do you think.

Any examples of how to read/write into EEPROM? The datasheet is a bit confusing.
 
**broken link removed**

there's an example of EEPROM writing done in BoostC. Shouldn't take much to port to C18.

these lines:

Code:
   EECON2=0x55;
   EECON2=0xAA;
   set_bit( EECON1, WR );       // start writing

are timing-sensitive, so if you can replace them with inline assembly that would be better. (C sometimes inserts other stuff between those types of commands that messes up EEPROM writing)
 
One thing that comes to my mind. Are you using C? Because if so, most C compilers require the entire array to be within the same page, ie within 256 bytes in size.
In your case, float may be stored as a 32-bit type. If possible, try reducing element count to 50 and try if the same error occurs.
 
I made a c program to write into the eeprom, it compiles but nothing is written. Could someone check it and spot the problem please.

thanks in advance,

#include "p18f4620.h"
#include <stdlib.h>
#include <math.h>

unsigned int readDataEE (unsigned int data)
{
EEADR = 0x0040;
EEADRH = 0x0001;
EEDATA = data;
EECON1bits.EEPGD = 0;
EECON1bits.CFGS = 0;
EECON1bits.WREN = 1;
INTCONbits.GIE=0;
_asm
MOVLW 0x55
MOVWF EECON2,0
MOVLW 0xAA
MOVWF EECON2,0
_endasm
EECON1bits.WR=1;
while (EECON1bits.WR == 1){};
INTCONbits.GIE=1;
EECON1bits.WREN = 0;

}


void main (void)
{
readDataEE(0x0005);
}
 
I assume you are checking to see if anything is written by reading back the EEPROM with the programmer?

if so, do you have the EEPROM data read protect turned off? if it's not, it'll just read back all 0's.
 
It started with all FF so i guess nothing has been written to it. Do I have to erase the eeprom first before writing?
 
no, you dont have to erase it. I don't know, I would suggest searching for some example code to try. I did the EEPROM writing once before in CC5x, but it was pretty annoying. I finally got it working just by messing with it a bunch of times... try varying amounts of inline assembly.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top