View previous topic :: View next topic |
Author |
Message |
alimary158
Joined: 26 Jan 2012 Posts: 16
|
ring buffer and timers problem |
Posted: Fri Jan 27, 2012 4:52 am |
|
|
Hello, i am trying to write on sd card using Brush Electronics library! The library works great as i already tried it with a simpler program!
I now was trying to use a circular buffer with the interrupt of timer2 where i write the data on the sd card.
In my following code , the file .txt it is created in the sd card but nothing inside is written. I have been debugging all night for this code but i don't seem to find my mistake. I suppose there is a problem in the way I'm handling interrupts since even before i check the circular buffer, i try to write a constant string inside the sd card but it would never being written
so what am i doing wrong??
Has anyone some suggestions??
thank you so much any help would be gladly appreciated
Code: |
int16 data=85; // this the data i want to add in the buffer
#define RxADCQsize 32
volatile int16 RxBaseADC[RxADCQsize]; // this the declaration of my buffer
// Rx Ring Buffer control
volatile BYTE RxHeadADC;
BYTE RxTailADC;
#INT_timer2
void timer2_isr()
{
RxBaseADC[RxHeadADC++]=data;
// test if ring buffer wrap is required
if (RxHeadADC >= RxADCQsize)
RxHeadADC = 0;
}
void main (){
FIL fsrc; // file structures
FRESULT result; // FatFs function common result code
WORD btw, bw; // File R/W count
FRESULT FS_Status;
char pressure[64];
disable_interrupts(GLOBAL);
setup_timer_2 (T2_DIV_BY_16, 255, 6);
RxHeadADC=0;
RxTailADC=0;
enable_interrupts(GLOBAL);
do
{
FS_Status = f_mountdrv();
}
while (FS_Status);
strcpy(pressure,"prova1.txt");
result = f_open(&fsrc,&pressure, FA_OPEN_ALWAYS | FA_WRITE);
result = f_lseek(&fsrc, fsrc.fsize);
//write a string delimiter to each append data log
strcpy(pressure, "\r\nNewTrial \r\n");
btw=strlen(pressure);
result = f_write(&fsrc,pressure, btw, &bw);
//checking the buffer tail and head
disable_interrupts(int_timer2);
if (RxHeadADC != RxTailADC)
{
enable_interrupts(int_timer2);
sprintf(pressure,"Valore=%lu\r\n",RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC = 0;
f_write(&fsrc,pressure,strlen(pressure),&bw);
}
else
enable_interrupts(int_timer2);
f_close(&fsrc);
} |
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jan 27, 2012 7:21 am |
|
|
The write will be never executed in the example. I guess, you want some kind of repeat loop, but there isn't any. |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Fri Jan 27, 2012 7:41 am |
|
|
hello,
Thanks, where should I be putting a loop? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2012 8:59 am |
|
|
Well I'm confused as to _why_ you need the interrupt at all.
Perhaps you can try without it ?
Since I don't log using an SD card, I can't comment on the overall 'program' flow and you haven't told us important details like PIC type, compiler version. |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Fri Jan 27, 2012 9:18 am |
|
|
hello,
sorry for my lack in giving you details! I am using PIC18F46J50
I'm really new in programming with pic so I'm finding lot of difficulties and I'm sorry if I post code with lots of mistakes! I hope the same that you all will be willing to help me!
I have a project where i would like to get data from a pressure sensor using the pic adc conversion and log these datas into a sd card. I was trying to write on sd card in the timer interrupt because here I perform the adc conversion so i was thinking to directly send the adc values into the ring buffer! In the code I have posted I still didn't perform the adc conversion but I was simply trying to output into the buffer a constant data that I define myself.
In particular the library I am using its from Asmallri Brush Electronics.
My question is, why i am not able to write on sd? The file is created but it is like the writing won't happen both for the constant string "new trial" and the buffer content.
p.s.i already know all my hardware and the libraries are working since i tested them with a simple program where i write on sd card in the main loop and everything works perfectly!
I am getting troubles with this buffer and interrupts.
Please help me out because i feel so lost in this. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2012 9:48 am |
|
|
Ok... so build on what you know works !
Forget about interrupts..
Just create a simple program....
something like this.....
main()
init...open up sd file,setup rs232 if needed, etc...
loop() {
counter =counter +1;
read adc.....
toggle_red_LED();
delay_ms(50);
save counter and adc values to sdcard file
toggle_grn_LED();
delay_ms(50);
}
counter is the number of reading
read adc...a function to read the pressure sensor
toggle_red_LED(); function to show you read the adc...
delay_ms(50); simple inline delay to slow things down..
save counter/reading... where you save data to sd card...
toggle_grn_LED(); function to show you've stored data to sd card.
another delay to slow things down...
Since you've already go the PIC and SDcard to talk to each other, I have to assume you have the proper interface chip for +5 to +3 conversion... |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Fri Jan 27, 2012 12:37 pm |
|
|
This is a good idea you are giving me but in my project i need to sample the analogue signal of the pressure sensore at about 200Hz and i don't know if there is a setting for my pic18f46j50 to reach these values of frequencies
so thats why i wanted to use the timer and put an interrupt at 200 hz and inside the timer make the conversion |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Jan 27, 2012 1:01 pm |
|
|
200Hz rate is 5ms overall 'loop'
You'll have to do 'the math' as I have no idea what procesor speed you have, how long it takes to save data to the SD drive, code in the loop,etc.
One way to 'ballpark' the 'looptime' is to toggle an I/O pin with LED attached in a test program. A 'forever' loop of read adc,save to sd, toggle LED,loop again. Then using a scope measure the 'looptime'.If less than 5 ms, then 200 Hz can be easily done. If not, you'll need to create ring buffers and store the accumulated data in amounts that the SD drive is designed for.A drive/sd card might like 512 byte blocks of data,you'll have to read up on the card you're using not all cards are the same. Also you'll have to be sure your PIC has enough RAM to store the data in a buffer. If the PIC only has 368 bytes and you need 512, you're out of luck. Also HOW you store the data is important and depends on what you do with it later.If you want continous readings, the buffers need to be big enough to staore 'raw data' while the SD card is being written to.
In my dataloggers I use Vinculums with USB flashdrives,saving the data in CSV format.Super fast(200 Hz is easy...) and any PC can automatically open the datafile into Excel. |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Fri Jan 27, 2012 1:03 pm |
|
|
Yes thats why i was trying to work out on the buffer implementation!
I even got a OpenLog product that directly works great to write data on sd but i was trying to implement my own code with the ring buffer using Brush electronics library.
thank you for your suggestions |
|
|
|