|
|
View previous topic :: View next topic |
Author |
Message |
alimary158
Joined: 26 Jan 2012 Posts: 16
|
Creating multiple files in SD |
Posted: Wed Feb 08, 2012 2:57 am |
|
|
Good morning to everyone.
I am using a PIC18F46J50 and i have written a program for writing on SD using Brush Electronics libraries.
I have written a program to log data and opening a file, write the data inside and then closing the file. All seems to work fine but i would like now to take a step ahead! I was trying to create multiple files in the SD. i have a timer2 interrupt every 5 ms from where i would like to read data from a sensor so i was planning to create a new file every time a certain number of samples has been acquired. Lets say for now 120 samples.
My problem is that now I manage to write just in the first file. The other files are created but nothing written inside. why is that??
In my code I have put a variable for counting the number of samples that is the count variable, which increments in the timer 2 interrupt.
Then in the main body of the program there is the check if the counting reaches the maximum number of samples, if so then the filename number is incremented and the f_close function is called.
fsrc variable represent a struct that includes the pointer to the file and it is used for the operations of opening, creating, writing on file.
To my logic they seem all right but why nothing is written in the files expect than the first one?
thank you
Code: |
int FIleNameNumber=0;
#INT_timer2
void timer2_isr()
{
data=data+1;
count++;
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[32];
disable_interrupts(GLOBAL);
restart_wdt();
init_pic();
setup_timer_2 (T2_DIV_BY_16,255,6);
RxHeadADC=0;
RxTailADC=0;
clear_interrupt(INT_RDA);
enable_interrupts(INT_RDA);
enable_interrupts(int_timer2);
enable_interrupts(GLOBAL);
while(1){
do
{
FS_Status = f_mountdrv();
}
while (FS_Status);
if (index>=MAX){
FileNameNumber++;
index=0;
f_close(&fsrc);
}
// The file is now closed so fsrc can now be reused
sprintf(pressure,"help%d.txt",FileNameNumber);
f_open(&fsrc,&pressure,FA_OPEN_ALWAYS | FA_WRITE);
result=f_lseek(&fsrc,fsrc.fsize);
disable_interrupts(int_timer2);
//while
while(RxHeadADC != RxTailADC)
{
enable_interrupts(int_timer2);
// here we have data waiting to be written
sprintf(pressure,"%lu\r\n",RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC=0;
result=f_write(&fsrc,pressure,strlen(pressure),&bw);
}
enable_interrupts(int_timer2);
f_close(&fsrc);
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Wed Feb 08, 2012 6:40 am |
|
|
When you say no data is written to file 2,3,4,....
Do you mean the files only have zeros written as the data or that the files have nothing in them( zero length) ?
They aren't the same.
To debug, I would create a small program with known filenames and data
ie: file1.txt, file2.txt,etc.
ie: data for file1.txt, 'file1','1','one' ; data for file2.txt, 'file2','2','two'.
That way you KNOW what is suppposed to be written into the files.
Get rid of all other code(timers,ISRs,pointers,buffers,etc.
Just staight inline code....NOTHING fancy.
Once that works, build from it,say a loop of 5 to autoincrement and save 5 KNOWN sets of data to 5 new files.
The key is to KNOW what data is and where it should be. |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Wed Feb 08, 2012 7:11 am |
|
|
Thank you!
I mean that nothing is written that the file is blank. Just the file_0 is written while the others are all blank.
I will try now to type something simpler and see if it is working
thanks i will post back soon |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
Back here |
Posted: Sat Feb 11, 2012 4:59 am |
|
|
From your suggestion i have created a simpler code where i decide to create TWO files. Each file is created when 120 samples are acquired.
SO i create first file, write 120 numbers (they are incrementing so from 1 i count to 120), then close the first file.
Then i open second file, write another 120 , and then close it.
I am encountering the same problem as before, and i get that the only file being written is the first one. while the second one is empty blank.
I paid attention in closing the file in my code in good way but still i get no changing in this problem. I also used separate FIL structures for creating and dealing with each different file but i always get the same.
Please can someone help me out? thank you
Code: |
int16 data=1;
int16 MAX=120;
int16 index=0;
int value=0;
#define RxADCQsize 64
volatile int16 RxBaseADC[RxADCQsize];
// Rx Ring Buffer control
volatile BYTE RxHeadADC;
BYTE RxTailADC;
int FileNameNumber =1;
#INT_timer2
void timer2_isr()
{
data=data+1;
index++;
if (index==MAX){
value=1;
index=0;
}
RxBaseADC[RxHeadADC++]=data;
// test if ring buffer wrap is required
if (RxHeadADC >= RxADCQsize)
RxHeadADC = 0;
}
void main (){
FIL fsrc,f1,f2; // file structures
FRESULT result; // FatFs function common result code
WORD btw, bw;
FRESULT FS_Status;
char pressure1[16];
char pressure2[16];
disable_interrupts(GLOBAL);
restart_wdt();
// Pic Inizialization
init_pic();
setup_timer_2 (T2_DIV_BY_16,255,6);
RxHeadADC=0;
RxTailADC=0;
clear_interrupt(INT_RDA);
enable_interrupts(INT_RDA);
enable_interrupts(int_timer2);
enable_interrupts(GLOBAL);
FS_Status = f_mountdrv();
while(FileNameNumber==1){
sprintf(pressure1,"prova%d.txt",FileNameNumber);
f_open(&f1,pressure1,FA_OPEN_ALWAYS | FA_WRITE);
result=f_lseek(&f1,f1.fsize);
disable_interrupts(int_timer2);
while(RxHeadADC != RxTailADC)
{
enable_interrupts(int_timer2);
// here we have data waiting to be written
sprintf(pressure1,"%lu\r\n",RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC=0;
result=f_write(&f1,pressure1,strlen(pressure1),&bw);
}
enable_interrupts(int_timer2);
result=f_close(&f1);
if(value==1){
value=0;
FileNameNumber++;}
}
while(FileNameNumber==2){
sprintf(pressure2,"prova%d.txt",FileNameNumber);
f_open(&f2,pressure2,FA_OPEN_ALWAYS | FA_WRITE);
result=f_lseek(&f2,f2.fsize);
disable_interrupts(int_timer2);
while(RxHeadADC != RxTailADC)
{
enable_interrupts(int_timer2);
// here we have data waiting to be written
sprintf(pressure2,"%lu\r\n",RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC=0;
result=f_write(&f2,pressure2,strlen(pressure2),&bw);
}
enable_interrupts(int_timer2);
result=f_close(&f2);
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sat Feb 11, 2012 7:12 am |
|
|
I'm 'old school' and still like the KISS principal especially for debugging.
I'd create a simple test program like....
start...
open file 'file1.txt'
write 'filenumber one'
close file #1
delay say 1/2 second
open file 'file2.txt'
write 'filenumber TWO'
close file #2
stop
no interrupts, no fancy data creation,no string manipulation, just hard,embedded filespecs and data.Nothing 'fancy', just a bare bones test to eliminate 'distractions', potential coding issues( missing brackets,wrong file names).
The simpler the test the easier and faster to getting it right. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat Feb 11, 2012 10:35 am |
|
|
The issue is the code calls commercial software from Bush Electronics...if it doesn't work with this code then talking to them first might be in order. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Feb 11, 2012 4:29 pm |
|
|
I too think the test program is too difficult.
One possible cause for failing is a missing handler for the enabled RDA interrupt. This would cause your program to hang on the first received character.
Follow the advice of Temtronic and make an easy as possible program. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Mon Feb 13, 2012 3:41 am |
|
|
This example will write to multiple files. If the file to be written to does not exist it will be created. If the file already exists it will be appended to.
Code: |
#CASE
//////////////////////////////////////////////////////////////////////////
// Main File for the SD/MMC File System Demonstration
// CCS PCH Specific file for the PIC18F series
//
// *** MULTIFILE BASIC EXAMPLE ***
//
// Copyright (c) 2006-2012, Andrew Smallridge
//
// Revision History
// 13/02/12 Multifile example
// 13/04/10 BASIC EXAMPLE
// 21/01/09 Ver 1.0 SHDC Support Integrated
// 08/01/09 Version 0.2 incorporating TINY FAT
//
// The FAT Library supports two RAM memory models. The performance
// (standard mode) and the lite mode.
//
// In Performance mode, each file has a dedicated 512 read/write cache.
// File reads and writes are performed to the dedicated cache. Reading
// and writing to the actual media occurs either when reads or write
// operation falls outside the cache or as a result of a call to
// f_close() or f_sync() for the file.
//
// In Lite mode, no spearate file cache is used. File read and write
// oprerations are performed using the file system file control block
//
// RAM Requirements:
// MODE File System Overhead Per Open File Overhead
// Performance 556 bytes 540 bytes
// Lite 556 bytes 28 bytes
//
// The #define USE_FAT_LITE configures the filesystem for FAT Lite operation
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Key Peripheral Usage
// Timer 0 Used for the general purpose 1ms system timer
// Timer 2 1ms clock for SW Real Time Clock
// USARTx Serial interface
// SPI/I2Cx SPI Mode: SD Card
//
// Timer 0
// General purpose 1ms system timer
// A 100ms system clock, TMR_100ms, is derived from the 1ms tick.
//
// Variable Timers TMR_Short and TMR_Long are derived from Timer 0
// and are avaiable for application specific timer functions. Each
// count value corresponding to 1ms. These timers are implemented
// as countdown timers.
// TMR_Short (8 bit) provides rollover in the range of 1 to 256ms (+1ms to -0ms)
// TMR_Long (16 bit) provides rollover in the range of 1 to 65536ms (+1ms to -0ms)
//
// Timer 2
// Used for the interrupt driven software RTC fuction.
// Timer 2 causes an interrupt every 1ms. The interrupt handler is used to derive
// rtc.hour (0 to 23), rtc.min(0 to 59), rtc.sec(0 to 59), rtc.ms100(0 to 9) and
// rtc.DOY (0 to 366), rtc.year
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Specify the file system mode
///////////////////////////////////////////////////////////////////////////
#define USE_FAT_LITE // configure the filesystem for FAT Lite operation
///////////////////////////////////////////////////////////////////////////
// Configure the platform specific equates
///////////////////////////////////////////////////////////////////////////
// define the hardware platform
//#define Sample_2525
//#define Sample_2455
//#define LJCV_PICNET1 2620
//#define LJCV_PICNET1 2685
//#define LJCV_PICNET1 4620
//#define LJCV_PICNET1 4685
//#define BE_2620_ENC
//#define BE_4620_ENC
#define HPC_SD_PICTAIL
// include the platform specific I/O configuration
#include <platform.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "ff.h"
DWORD get_fattime(void)
{
return 0;
}
void file_list(char *ptr)
///////////////////////////////////////////////////////////////////////////
// void file_list(char *ptr)
//
// Lists the contents of a text file
///////////////////////////////////////////////////////////////////////////
{
FIL fsrc;
FRESULT result; // FatFs function common result code
char mesg[32];
result = f_open(&fsrc, ptr, FA_OPEN_EXISTING | FA_READ);
// display the contents of the file
if (result == FR_OK)
{
WORD i, br;
// Display the file's FIL data structure
// f_show_FIL_structure(&fsrc);
do
{
result = f_read(&fsrc, mesg, sizeof(mesg), &br);
for (i = 0; i < br; i++)
putc(mesg[i]);
} while ((result == FR_OK) && br);
// Display the file's FIL data structure
// f_show_FIL_structure(&fsrc);
if (result != FR_OK)
{
printf("TYPE command ERROR\r\n");
f_get_error_mesg(result,mesg);
printf("FILE SYSTEM ERROR - %s\r\n",mesg);
}
// Close all files
f_close(&fsrc);
printf("\r\n");
}
else
{
f_get_error_mesg(result,mesg);
printf("FILE SYSTEM ERROR - %s\r\n",mesg);
}
}
void init_pic(void)
///////////////////////////////////////////////////////////////////////////
// void init_pic(void)
//
// Initialise the hardware defaults
///////////////////////////////////////////////////////////////////////////
{
setup_spi(FALSE);
setup_spi2(FALSE);
setup_wdt(WDT_OFF);
#if defined AD1PCFG_Def
AD1PCFG = AD1PCFG_Def;
#endif
#if defined AD1PCFGL_Def
AD1PCFGL = AD1PCFGL_Def;
#endif
#if defined AD1PCFGH_Def
AD1PCFGH = AD1PCFGH_Def;
#endif
#if defined PA_DefData
// initialise port A
output_a(PA_DefData);
set_tris_a(PA_DefTRIS);
#endif
#if defined PB_DefData
// initialise port B
output_b(PB_DefData);
set_tris_b(PB_DefTRIS);
#endif
#if defined PC_DefData
// initialise port C
output_c(PC_DefData);
set_tris_c(PC_DefTRIS);
#endif
#ifdef PD_DefData
// initialise port D
output_d(PD_DefData);
set_tris_d(PD_DefTRIS);
#endif
#ifdef PE_DefData
// initialise port E
output_e(PE_DefData);
set_tris_e(PE_DefTRIS);
#endif
#ifdef PF_DefData
// initialise port F
output_f(PF_DefData);
set_tris_f(PF_DefTRIS);
#endif
#ifdef PG_DefData
// initialise port G
output_g(PG_DefData);
set_tris_g(PG_DefTRIS);
#endif
#ifdef PH_DefData
// initialise port H
output_h(PH_DefData);
set_tris_h(PH_DefTRIS);
#endif
#ifdef PJ_DefData
// initialise port J
output_j(PJ_DefData);
set_tris_j(PJ_DefTRIS);
#endif
#if defined PLLFBD_Def
PLLFBD = PLLFBD_Def;
#endif
#if defined CLKDIV_Def
CLKDIV = CLKDIV_Def;
#endif
#if defined UART1_TX_RPR
UART1_TX_RPR = 3; // UART1 TX
#endif
#if defined UART1_RX_RP
UART1_RX_RPR = UART1_RX_RP;
#endif
#if defined UART2_TX_RPR
UART2_TX_RPR = 5; // UART2 TX
#endif
#if defined UART2_RX_RP
UART2_RX_RPR = UART2_RX_RP;
#endif
#if defined SPI1_SDI_RP
SPI1_SDI_RPR = SPI1_SDI_RP;
SPI1_SDO_RPR = 7; // SPI1 SDO
SPI1_CLK_RPR = 8; // SPI1 CLK
#endif
#if defined SPI2_SDI_RP
SPI2_SDI_RPR = SPI2_SDI_RP;
SPI2_SDO_RPR = 10; // SPI2 SDO
SPI2_CLK_RPR = 11; // SPI2 CLK
#endif
}
BYTE write_test (char *ptr)
///////////////////////////////////////////////////////////////////////////
// BYTE write_test (char *ptr)
//
// Opens the file pointed to by ptr and writes to it. If the file exists it
// is appended to. If it does not exist it is created. The file this
// then closed.
///////////////////////////////////////////////////////////////////////////
{
FIL fsrc; // file structures
FRESULT result; // FatFs function common result code
WORD btw, bw; // File R/W count
char mesg[64];
// open the file - assumes target is the filename
result = f_open(&fsrc, ptr, FA_OPEN_ALWAYS | FA_WRITE);
if (result)
{
printf("write_test FS ERROR on file_open\r\n");
goto Ex_write_test_no_close;
}
// Move to end of the file to append data
result = f_lseek(&fsrc, fsrc.fsize);
// write a short string to destination file
// strcpy(mesg, "My String!");
strcpy(mesg, ptr);
btw = strlen(mesg);
result = f_write(&fsrc, mesg, btw, &bw);
if (result)
{
printf("write_test FS ERROR on f_write\r\n");
goto Ex_write_test;
}
// write another short string to destination file
strcpy(mesg, "\r\nHello \r\n");
btw = strlen(mesg);
result = f_write(&fsrc, mesg, btw, &bw);
if (result)
{
printf("write_test FS ERROR on second f_write\r\n");
goto Ex_write_test;
}
// example of syncing the file system
// not really needed here becasue we are about the
// close the file anyway
printf("syncing the file\r\n");
result = f_sync(&fsrc);
if (result)
{
printf("write_test: Error returned from f_sync\r\n");
goto Ex_write_test;
}
printf("about to close the file\r\n");
f_close(&fsrc);
printf("\r\n");
return(result);
Ex_write_test:
// Close the file
f_close(&fsrc);
return (result);
Ex_write_test_no_close:
printf("\r\n");
return (result);
}
void main ()
{
int i;
FRESULT FS_Status;
char target[16];
disable_interrupts(GLOBAL);
restart_wdt();
init_pic();
// initialise the interrupts
// this will intialise both the global and priority interrupts
clear_interrupt(INT_RDA);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
printf("\r\nBasic Application - compiled %s %s\r\n\r\n", __DATE__,__TIME__);
// initialise the media and filesystem
// this will loop until the card is found
do
{
FS_Status = f_mountdrv();
}
while (FS_Status);
for (i = 0; i<5; i++)
{
// build the file name
sprintf(target,"File%u.txt",i);
printf("Performing write testing to file %s..\r\n",target);
write_test(target);
}
for (i = 0; i<5; i++)
{
// build the file name
sprintf(target,"File%u.txt",i);
printf("Displaying the contents of the file %s..\r\n",target);
file_list(target);
}
printf("That's all Folks..\r\n");
for (;;)
;
}// End of main()...
|
Here is the output from the first run:
Code: |
File0.txt
Hello
Displaying the contents of the file File1.txt..
File1.txt
Hello
Displaying the contents of the file File2.txt..
File2.txt
Hello
Displaying the contents of the file File3.txt..
File3.txt
Hello
Displaying the contents of the file File4.txt..
File4.txt
Hello
That's all Folks..
|
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
|
|
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
|