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 CCS Technical Support

Problem Datalogger with SD Card 2G Fat16

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
emyeuKH



Joined: 22 Sep 2015
Posts: 4

View user's profile Send private message

Problem Datalogger with SD Card 2G Fat16
PostPosted: Tue Aug 23, 2016 4:05 am     Reply with quote

Hi everybody. Have a nice day.
I try to make a file to save some data and i see difficult problem with SD Card. I am using Pic18F4620, CCS 5.036 and SDCard board as picture for testing before make a real board.
First, code tested on Proteus and after that tested on external real hardware.
Everything connected same in Proteus. Problem that: can't make a file log.txt to save data. I hope you can help me. I have two question:
1. Where is the error problem in code which it can't make file log.txt?
2. Now i use SD 2G format Fat16. I hope i can use a popular SD with memory lager on market as 4G, 8G, 16G with format Fat32. Could you tell me how to do so, please?
Thank you very much.

Picture of SD Card: Top to Bottom: 1.GND 2.3V3 3.5V 4.CS 5.Mosi 6.SCK 7.Miso 8.GND
And microSD Card: 1.CS 2.SCK 3.Mosi 4.Miso 5.VCC 6.GND

All files in SD Card.rar (included Proteus Simulator): http://www.mediafire.com/download/6lexlevvq5qnejs/SD_Card.rar

Code:
Code:
#include <18F4620.h>                                                                             
#device PASS_STRINGS = IN_RAM   
#device *=16 ADC=8                 
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG                 
#use delay(clock=20000000)
//#use rs232(FORCE_SW,baud=9600,parity=N,xmit=PIN_E0,rcv=PIN_E1,bits=8,stream=DEBUG,errors)//su dung uart mem     
#use rs232(UART1,baud=9600,parity=N,bits=8,stream=DEBUG,errors)//su dung uart mem
#define ledv  PIN_C2                                                     
#define ledr  PIN_C1
#define ledon output_low                                     
#define ledoff output_high                     
#define led_on output_low                                                     
#define led_off output_high                                                       
/*#define LCD_ENABLE_PIN PIN_D2                   
#define LCD_RS_PIN PIN_D0               
#define LCD_RW_PIN PIN_D1               
#define LCD_DATA4 PIN_D4                                           
#define LCD_DATA5 PIN_D5             
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7                                             
#include <lcd.c>*/
#include ".\_inc\driverLCD.h"                                 //xong
#define DS1820_DATAPIN  PIN_B3             
#include ".\_inc\types.h"                                       //xong
#include ".\_inc\driverDS1307.h"                           //xong
#include ".\_inc\stdlib.h"                                    //atoi32             
#include ".\_inc\mmcsd.c"                                       //xong
//#include ".\_inc\mmc_spi.c"
#include ".\_inc\fat.c"                                          //
#include ".\_lib\ds1820.h"

//////////////////////                                           
///                ///
/// Useful Defines ///
///                ///
//////////////////////

#define COMMAND_SIZE 10                                                 
#define NUM_COMMANDS 11

////////////////////////
///                  ///
/// Global Variables ///
///                  ///                                                                                                                                                         
////////////////////////

char g_CWD[200] = "/"; //current working directory



sint16 temperature_raw;     
float temperature_float;
char temperature[8];       
uint8 sensor_count;
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
char Buffer_time[13];
int8 Hour,Min,Sec,Day, Mon, Year;
int8 CharRec  = 0;
int1 ComRec;
////////////////////////////////
///                          ///
/// Function Implementations ///
///                          ///
////////////////////////////////
                                                         


/*
Summary: Deletes a file.
Param: The full path of the file to delete.
Returns: None.
*/
void DeleteFile(char *fileName)
{
   printf("\r\nDeleting '%s': ", fileName);
   if(rm_file(fileName) != GOODEC)
   {
      printf("Error deleting file");
      return;
   }
   printf("OK");
}

/*
Summary: Creates a file.
Param: The full path of the file to create.
Returns: None.
Example Usage: \> make "Log.txt"
*/
void MakeFile(char *fileName)
{
   printf("\r\nMaking file '%s': ", fileName);
   if(mk_file(fileName) != GOODEC)
   {
      printf("Error creating file");
      return;
   }
   printf("OK");                               
}

/*
Summary: Append a string to a file.
Param: The full path of the file to append to.
Param: A pointer to a string to append to the file.
Returns: None.
Example Usage: \> append "Log.txt" "This will be appended to the end of Log.txt"
Note: A "\r\n" will be appended after the appendString.
*/
void AppendFile(char *fileName, char *appendString)
{
   FILE stream;
   printf("\r\nAppending '%s' to '%s': ", appendString, fileName);
   if(fatopen(fileName, "a", &stream) != GOODEC)
   {                   
      printf("Error opening file '%s'",fileName);
      return;
   }
   
   fatputs(appendString, &stream);
   fatputs("\r\n", &stream);
                                               
   if(fatclose(&stream) != GOODEC)
   {
      printf("Error closing file");
      return;
   }
   printf("OK");
}

/*
Summary: Change the working directory.
Param: The new working directory to switch to.
Returns: None.                             
Example Usage: \> cd ftp/     -> /ftp/
               \ftp\> cd files/  -> /ftp/files/
               \ftp\files> cd..  -> /ftp/
               \ftp\> cd ..      -> /
               \> cd /ftp/files/ -> /ftp/files/
               
Note: Changing the directory to .. will go up a directory.
*/
void ChangeDirectory(char *newCWD)
{
   FILE stream;
   
   //append a / to the end of the filename if it doesn't exist
   //making an assumption here that newCWD can hold 1 more character
   if (newCWD[strlen(newCWD)-1] != '/')
     strcat(newCWD, "/");

   if((strstr(newCWD, "../") != 0) && (strcmp(g_CWD, "/") != 0))
   {
      g_CWD[strlen(g_CWD) - 1] = '\0';
           
      g_CWD[strrchr(g_CWD, '/') - g_CWD + 1] = '\0';     
   }
   else
   {
      if(fatopen(newCWD, "r", &stream) != GOODEC)
      {
         printf("\r\nError changing directory");
         return;
      }
      strcpy(g_CWD, newCWD);
   }
}                               
                     
/*
Summary: Display the contents of the working directory.
Param: The full path of the directory contents to display.
Returns: None.
Example Usage: /> dir
*/
void DisplayDirectory(char *dir)
{
   disp_folder_contents(dir); 
}

/*
Summary: Create a directory.
Param: The full path of the directory to create.
Returns: None.
Example Usage: /> mkdir "Backlog"
*/
void MakeDirectory(char *dir)
{
   //append a / to the end of the filename if it doesn't exist
   //making an assumption here that newCWD can hold 1 more character
   if (dir[strlen(dir)-1] != '/')
     strcat(dir, "/");   

   printf("\r\nMaking directory '%s': ", dir);
                         
   if(mk_dir(dir) != GOODEC)
   {
      printf("Error creating directory");
      return;
   }
   printf("OK");
}

/*
Summary: Remove a directory.
Param: The full path of the directory to remove.
Returns: None.
Example Usage: /> rmdir "Backlog"
Note: The directory needs to be empty in order for this command to work.
*/                                                             
void RemoveDirectory(char *dir)
{
   printf("\r\nRemoving directory '%s': ", dir);

   //append a / to the end of the filename if it doesn't exist
   //making an assumption here that newCWD can hold 1 more character                                                                     
   if (dir[strlen(dir)-1] != '/')
     strcat(dir, "/");

   if(rm_dir(dir) != GOODEC)
   {
      printf("Error removing directory");
      return;
   }
   printf("OK");
}

#define CAT_FROM_START  FALSE
#define CAT_FROM_END    TRUE
/*
Summary: Prints either all of or the last 80 characters in a file.
Param: The full path of the file to print off.
Param: If true, this function will print off the last 80 characters in the file.
       If false, this funciton will print off the entire file.
Returns: None.
Example Usage: /> cat "Logs.txt" (this will display the entire file)
Example Usage: /> tail "Logs.txt" (this will display the last 80 characters in the file)
*/
void PrintFile(char *fileName, int1 startFromEnd)
{
   FILE stream;

   if(fatopen(fileName, "r", &stream) != GOODEC)
   {
      printf("\r\nError opening file '%s'",fileName); 
      return;
   }

   printf("\r\n");

   if(startFromEnd)                                   
      fatseek(&stream, 80, SEEK_END);

   fatprintf(&stream);
   
  // fatclose(&stream);
   if(fatclose(&stream) != GOODEC)
   {
      printf("Error closing file '%s'",fileName);
      return;
   }
}

/*
Summary: Formats the media to a specified size.
Param: The size of the media, in kB, in string form.
Returns: None.
Example Usage: /> format 524288 (format a 512MB card)
*/
void FormatMedia(char *mediaSize)
{
   int32 size;
   
   size = atoi32(mediaSize);
   
   printf("\r\nFormatting media (size=%LU): ", size);
 
   if(format(size) != GOODEC)                                             
   {
      printf("Error formatting media");
      return;
   }
   printf("OK");
}


char * GetCMD(char *in)
{
   char tokens[]=" \r\n";
   return(strtok(in,tokens));
}

char * GetOption(char *in)
{
   char tokensSpace[]=" \r\n";
   char tokensQuote[]="\"\r\n";
   
   //trim leading spaces
   while (*in==' ')
      in++;
   
   //if first char is a quote, then end token on a quote.  ELSE end token on a space
   if (*in == '\"')
      return(strtok(in,tokensQuote));
   else
      return(strtok(in,tokensSpace));
}
 


void ProcesaTime() {
   int8 i=0;
   int1 ChangeH, Changem, ChangeS;   
   int1 ChangeD, ChangeM, ChangeY; 

   ChangeH=0;
   Changem=0;
   ChangeS=0;   
   ChangeD=0;
   ChangeM=0;
   ChangeY=0;

   while (i<CharRec) {
      if ((Buffer_time[i]=='h') || (Buffer_time[i]=='H')) {
         ChangeH=1;
         Changem=0;
         ChangeS=0;             
         Hour=0;
      }             
      if (Buffer_time[i]=='m') {
         Changem=1;
         ChangeH=0;
         ChangeS=0;
         Min=0;
      }
      if ((Buffer_time[i]=='s') || (Buffer_time[i]=='S')) {
         ChangeS=1;
         ChangeH=0;
         Changem=0;
         Sec=0;
      }
     
      if ((Buffer_time[i]=='d') || (Buffer_time[i]=='D')) {
         ChangeD=1;
         ChangeM=0;
         ChangeY=0;
         Day=0;
      } 
      if (Buffer_time[i]=='M') {
         ChangeD=0;
         ChangeM=1;
         ChangeY=0;
         Mon=0;
      }
      if ((Buffer_time[i]=='y') || (Buffer_time[i]=='Y')) {
         ChangeD=0;
         ChangeM=0;
         ChangeY=1;
         Year=0;
      }
     
      if ((Buffer_time[i]>='0') && (Buffer_time[i]<='9')) {
         if (ChangeH)
            Hour=(Hour*10+Buffer_time[i]-48);
         if (Changem)                 
            Min=(Min*10+Buffer_time[i]-48);
         if (ChangeS)
            Sec=(Sec*10+Buffer_time[i]-48);
         if (ChangeD)
            Day=(Day*10+Buffer_time[i]-48);
         if (ChangeM)
            Mon=(Mon*10+Buffer_time[i]-48);
         if (ChangeY)
            Year=(Year*10+Buffer_time[i]-48);
      }                                                       
      if ((Buffer_time[i]=='r') || (Buffer_time[i]=='R'))
         reset_cpu();
      i++;
   }                                                 
   printf("\r\nH=%u,m=%u,S=%u\r\nD=%u,M=%u,y=%u\r\n",Hour,Min,Sec,Day,Mon,Year);
   ds1307_set_date_time(Day,Mon,Year,0,Hour,Min,Sec);      //Settime here
   CharRec=0;
   ComRec=0;
}

#INT_RDA
void serial_isr()
{
   char c;

   c=getc();
   putchar(c);                                                             
   Buffer_time[CharRec] = c;
   if (c==13)                   
   {
      ComRec=1;
      ProcesaTime();
   }
   else
      CharRec = (CharRec+1) % sizeof(Buffer_time);
}
void main(void)

   char buffer[255]; 
   char buff_date[15];
   char buff_time[15];
   char gfilename[32];
   int i;   // pointer to the buffer               
                               
   // initialize the FAT
   //  keep in mind that this will automagically initialize the media 

   lcd_init();                         
   printf (lcd_putc, "\fINITIALIZING FAT\n..."); 
   printf ("\r\nINITIALIZING FAT...");   
   delay_ms(500);                                             
   i = fat_init();                                                         

   if (i)                                                         
   {           
      printf("\r\n\nERROR INITIALIZING FAT\r\n\n"); 
      printf (lcd_putc, "\fERROR\nINITIALIZING FAT!!!!"); 
      return;
   }                                                                               
   else             
   {                                                                   
      printf("\r\n\nSUCCESS INITIALIZING FAT\r\n\n");   
      printf(lcd_putc, "\nSUCCESS ");                                                       
   }                                                                                                                 
      ds1307_init();                                                                                                   
                                             
      // Set date for -> 21/11/2014 fri
      // Set time for -> 14:34:00
      //ds1307_set_date_time(21,11,14,5,14,34,00);      //Settime here
                                                                                               
      printf(lcd_putc, "\nLog to File");             
      strcpy(gfilename,"/log.txt");     
      strcpy(buffer,"Mualinhkien.vn");       
      MakeFile(gfilename);
      AppendFile(gfilename,buffer);//Ghi du lieu vao file log.txt
      int loop=0;                                                                                   
      if ( DS1820_FindFirstDevice() )         
        {
                                                                                                           
               
               temperature_raw = DS1820_GetTempRaw();
               DS1820_GetTempString(temperature_raw, temperature);
               temperature_float = DS1820_GetTempFloat();   
             
             
        }
   enable_interrupts(INT_RDA);   
   enable_interrupts (GLOBAL);
   printf(lcd_putc, "\f");   
   while(TRUE)                                                       
   {               

   loop++;
     sprintf(buffer,"Sensor %d:%f°C", sensor_count,temperature_float);   
     
     ds1307_get_date(day,month,yr,dow);                                                                                             
     ds1307_get_time(hrs,min,sec);                                                                                 
                                                         
     sprintf(buff_time," - %02d:\%02d:\%02d",hrs,min,sec);
     strcat(buffer,buff_time); 
     lcd_gotoxy(1,1);   
     printf(lcd_putc,"%02d:\%02d:\%02d\n", hrs,min,sec);     
     sprintf(buff_date," %02d/\%02d/\%02d ",day,month,yr);
     strcat(buffer,buff_date); 
     printf(lcd_putc,"\n%02d/\%02d/\%02d",day,month,yr);   
    // printf("\r\n%s\r\n",buffer);   
     lcd_gotoxy(10,1);   
     printf(lcd_putc, "Sensor");   
     lcd_gotoxy(10,2);                                   
     printf(lcd_putc, "%f°C",temperature_float);
     lcd_gotoxy(15,2);
     printf(lcd_putc, "%c",223); //Do C   
     if(loop==10)//10 second             
     {                                                                                                         
     loop=0;
     printf(lcd_putc,"\fLogging \nTo Micro SD Card");
     AppendFile(gfilename,buffer);//Ghi du lieu vao file log.txt
     if ( DS1820_FindFirstDevice() )
        {
                                                                                                           
                                                               
               temperature_raw = DS1820_GetTempRaw();
               DS1820_GetTempString(temperature_raw, temperature);
               temperature_float = DS1820_GetTempFloat();   
             
             
        }                                                                                                         
     }
     delay_ms(1000);
     
   }                                                             
}
temtronic



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

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 4:46 am     Reply with quote

odds are real good...
It's the Classic hardware design configuration error.

Five volt PIC, Three volt peripheral.

That PIC was designed for '5 volt operation' and according to your picture, your SD card module is a 3 volt device.
So powering both with 5 volts, PIC is happy and SD card blows up, power with 3 volts, SDC ard is happy but PIC will not run properly, if at all.

There are at least 3 ways to correct this.

1) properly choose a PIC that runs on 3 volts, at the speed you designed for.

2) install some kind of 'logic level interface' between the 5V PIC and the 3V SD card.

3) buy and use a 5 volt SD card.

As for the code, you should always confirm hardware by coding 'low level' diagnostics programs. 1HZ LED and I2C scanner are typical.

Jay
emyeuKH



Joined: 22 Sep 2015
Posts: 4

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 6:49 am     Reply with quote

#temtronic
Thank you very much - temtronic. Very clearly.
But is that really main problem? Because i tested them on Adruino board and they work good. Anything else for this problem? Please tell me more. Thanks
Now schematic board SD:

One way to fix it as you said:
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 7:34 am     Reply with quote

Problem is that an SD card at 3.3v, does not produce a high enough output voltage to drive the SDI pin of a 5v PIC.
You have voltage 'division' to lower the PIC output voltage, but nothing to raise the SD card output to feed the PIC.

This has been described here dozens of times. The input threshold for the PIC SDI pin (entry D041 in the data sheet), is 3.2v on your PIC at 5v.....

Three solutions:

1) The 'easy' software solution (though it will limit the speed), is to switch to using software SPI. You'd have to use #use spi, instead of the hardware SPI commands, with 'force_sw' selected, and spi_xfer instead of spi_read and spi_write, and connect the SDO pin from the SD card to a pin that has TTL thresholds instead of ST (any of port A, or B, except RA4).

2) Proper solution add a buffer that has TTL thresholds. Look at the circuit here:

http://www.smallridge.com.au/index.php?page=projects#HWREF

Load the 'ethernet reference design' for PIC18F4620, and look at how the SD card connections are done.

3) Even better, switch to a 3.3v PIC, and get rid of needing two power supply voltages. The LF version of the chip you have can run at up to 25MHz from 3.3v.

I see Temtronic already answered.

The Arduino has thresholds that depend on the board version. However most accept 3v, so can (just) work....

https://learn.sparkfun.com/tutorials/logic-levels

Start by just writing and reading a sector on the card. Only then try to get FAT working. I haven't looked at your code, but there are three patches to the standard CCS drivers in the code library, which allow > 2GB, fix one bug, and allow handling of many more cards. Use these.
temtronic



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

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 8:37 am     Reply with quote

Almost time to have a 'sticky' subject about this seeing how it comes up several times ,every couple of months. That way we could refer to 'go see the sticky' !

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 9:02 am     Reply with quote

I think I said the same last time!... Smile

I'd say we could drop the V5 sticky now (since V5 is working well), and have this instead.
emyeuKH



Joined: 22 Sep 2015
Posts: 4

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 12:50 am     Reply with quote

#Ttelmah
#temtronic
Thank you very much for reply.
Yesterday i'm busy so not reply for you, today i will review this problem. If having any problem, i will ask again for helping. Hoping you can help me and hope everything is ok. I will re-test and send message about my result for you.
Thank you and see you soon.
If anytime when you come to Ho Chi Minh City - Vietnam, i'm willing guide free for your travel.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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