|
|
View previous topic :: View next topic |
Author |
Message |
emyeuKH
Joined: 22 Sep 2015 Posts: 4
|
Problem Datalogger with SD Card 2G Fat16 |
Posted: Tue Aug 23, 2016 4:05 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Aug 23, 2016 4:46 am |
|
|
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
|
|
Posted: Tue Aug 23, 2016 6:49 am |
|
|
#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: 19552
|
|
Posted: Tue Aug 23, 2016 7:34 am |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Tue Aug 23, 2016 8:37 am |
|
|
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: 19552
|
|
Posted: Tue Aug 23, 2016 9:02 am |
|
|
I think I said the same last time!...
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
|
|
Posted: Thu Aug 25, 2016 12:50 am |
|
|
#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. |
|
|
|
|
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
|