Pages: [1]   Go Down
Author Topic: Program can't open file on SD card  (Read 162 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

   Hi guys, i've a problem.  I've made a sheme with 3 OneWire devices DS18B20 and a self made microSD shield. An idea is - find all OneWire devices, register them in a table, ask each one 1 time in 5 seconds 12 times and print data to a serial port (port monitor of Arduino IDE) and to a file on microSD card. If i comment a part of program which write data to a file, all the devices are found, table and temperature data from them printed to a serial. When i try to write it parallel to microSD, programm write "error opening test.txt",  BUT! if the file was not on microSD card, it magically appears with 0b size. If i try to write a simple data with a simple programm to a microSD card like "test 1, 2, 3" whithout any changing in wiring it works great. File appears, data writing to it and so on.  Please help me, I'll be glad for any suggestion.
A simple programm, works great:
Code:
#include <SD.h>

File myFile;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
  pinMode(10, OUTPUT);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

   myFile = SD.open("test.txt", FILE_WRITE);

  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening test.txt");
  }

  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
}

void loop()
{

}

And my programm:

Code:
//use OneWire
#include <OneWire.h>
#include <SD.h>

//OneWire on pin 9

OneWire ds(9);

//variables and massives
int HighByte, LowByte, TReading, Tc_100, Whole, Fract, SignBit;
byte i=0,devicenum=0,k=0,j=0,s=0,tempdata[16],address[8],addressmap[10][8];
String devicetype[10];
File myFile;


//setting up

void setup(void)
{
  Serial.begin(9600);
 
/*while devices appears, i find they addresses and write to a matrix whith 10 strings, so i use up to 10 devises in my programm*/
while (ds.search(address)){
for ( i = 0; i < 8; i++) addressmap[k][i]=address[i];
k=k+1;
}
//remember number of OneWire devices
devicenum = k-1;

/*for each device get a Byte which means type, and write it to another matrix*/
for (k=0; k<=devicenum; k++) {
  switch (addressmap[k][0]) {
  case 16: devicetype[k]="digital thermometer ds1820 (ds1920) series"; break;
  case 32: devicetype[k]="4-channel 16 bit analog->digital converter"; break;
  case 34: devicetype[k]="digital thermometer ds1822"; break;
  case 40: devicetype[k]="digital thermometer ds18b20, up to 12 bit resolution"; break;
  default: devicetype[k]="unknoun 1-Wire device"; break;
                            }
                             }
//print all the addresses and types of devices to a serial
for( k = 0; k <= devicenum; k=k+1) {
Serial.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
  for( i = 0; i < 8; i=i+1) {
    Serial.print(addressmap[k][i], HEX);
    Serial.print(" ");
                            }
    Serial.print(']'); Serial.print(" type of device is "); Serial.println(devicetype[k]);
                                   }
    Serial.println("That's all list of online devices");


   Serial.print("Initializing SD card...");
 
 // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
 //   Note that even if it's not used as the CS pin, the hardware SS pin
 //   (10 on most Arduino boards, 53 on the Mega) must be left as an output
 //   or the SD library functions will not work
 
 pinMode(10, OUTPUT);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
 
 // try to open the file
   
  myFile = SD.open("test.txt", FILE_WRITE);
 
  // if ok, then print all the addresses and types of devices to a file:
  if (myFile!=false) {
   
  // print to a serial, that i work whith file 
   Serial.print("Writing device mass to test.txt"); 
   
for( k = 0; k <= devicenum; k=k+1) {
myFile.print("Device #"); myFile.print(k); myFile.print(" address is [ ");
  for( i = 0; i < 8; i=i+1) {
  myFile.print(addressmap[k][i], HEX);
  myFile.print(" ");
                            }
    myFile.print(']'); myFile.print(" type of device is "); myFile.println(devicetype[k]);
                                   }
    myFile.println("That's all list of online devices");
   
// print to a serial, that i work whith file
   Serial.print("Writing devices data to test.txt"); 
// series of 12 measurements
 for( s = 0; s < 12; s=s++) {
    for( k = 0; k <= devicenum; k=k+1) {
      for(i=0;i<8;i++) address[i]=addressmap[k][i]; 
  ds.reset();
  ds.select(address);
  ds.write(0x44,1);         // converting
 
  delay(1000);     //maybe 750ms is enough
  ds.reset();
  // we might do a ds.depower() here, but the reset will take care of it.
    ds.select(address);   
  ds.write(0xBE);         // please, write data to a scratchpad
  for ( j = 0; j < 9; j++)   { // getting 9 Byte data from Scratchpad - page 9 from 27 Datasheet DS18B20
    tempdata[j] = ds.read();
  // we need only 0 and 1 Byte from Scratchpad - page 9 from 27 Datasheet DS18B20
  LowByte = tempdata[0];
  HighByte = tempdata[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) TReading = (TReading ^ 0xffff) + 1; // if negative, then 2's comp
 
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;
 
                              }
 for (i=0; i<8; i++) Serial.print(address[i],HEX); Serial.print("   "); Serial.print(tempdata[0],HEX); Serial.print("   "); Serial.print(tempdata[1],HEX); Serial.print('\n');
                              // If its negative
  Serial.print(" T = "); if (SignBit) Serial.print("-"); Serial.print(Whole); Serial.print("."); if (Fract < 10) Serial.print("0"); Serial.print(Fract); Serial.println(" C");
                                        }
    Serial.println("I'm waiting about 5 sec before next series of measurement");
    delay (5000);
                            }
    myFile.close();
    Serial.println("Done.");
              }
  // if the file did not open, writing to a serial error
  else Serial.println("error opening test.txt");
 
 }
void loop(void)
 {

 }
Logged

Sydney, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1250
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't use the SD library because I use SDFat, however, the line
Code:
if (myFile!=false)
is different from the shorter example and could be the problem.

myFile can be evaluated as a logical expression - as in "(myfile)" - because the C++ compiler will treat any non-zero value as 'true'. So a NULL pointer (typically zero) will evaluate as false, although I would prefer to explicitly use "pointer == NULL". By comparing "myFile != false" the expression is only logically true if myFile is not equal to the value false (and I don't know what it is). Maybe changing this to the same logic as the simpler example could make a difference.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A simple programm, works great:

If you run it twice, the file has the same data twice? It opens the file every time?

If so then

if (myFile!=false) {

is simply not doing what you think.

I ran your sketch through Autoformat and moved braces just looking for some other answer and got none.

So what happened when you used

if (myFile) {

which still doesn't answer why it would work with no file and not with a file present unless that was read-only.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Edison Member
*
Karma: 43
Posts: 1551
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think this:
Code:
if (myFile!=false) {

should be this:
Code:
if (myFile != NULL) {

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Edison Member
*
Karma: 43
Posts: 1551
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is also best to avoid use of the String class. It will eventually cause you grief. Use C null_terminated strings instead.

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

   To marco_c
   Thank you for your answer. I tried to write this part as in example
Code:
if (myFile) ...

and some other variants. Nothing of them works.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

   To GoForSmoke
Thank you for your answer.
The simple programm write "testing 1, 2, 3" many times. +1 each time i turn on Arduino or call a serial port monitor (port monitor of Arduino IDE).
Srting of code
Code:
if (myFile) {

gives a same result, don't work.
About a simple programm, it works with no file because string of code
Code:
myFile = SD.open("test.txt", FILE_WRITE);
create a file if it is not present. Whith read only file i did not try.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

   To el_supremo
Thank you for your answer. Will try.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

About a simple programm, it works with no file because string of code
Code:
myFile = SD.open("test.txt", FILE_WRITE);
create a file if it is not present. Whith read only file i did not try.


FILE_WRITE should create the file if none exists and start writing at the end of the new file, which is also the beginning.

However if the file exists then FILE_WRITE should open the file and start writing at the end, the writing there also called append (add to the end) in some languages and documents.

The simple program does those things. The problem in your code may be interrelated or not but it is not that simple at least to me which is a cue for someone else to point out an even simpler answer!

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

      To everyone.
Thank you very much for your answers.  Excuse me, I badly know the English language,
and do not understand all of what you write here. I'm from Russia.
With your help and help of my friend I found a solution, a bit strange in my opinion.
    
In the code I posted above it's enough to change one line:

Was:
Code:
String devicetype[10];

Now:
Code:
char* devicetype[10];
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

     Here is final version of code
Code:
//use OneWire
#include <OneWire.h>
#include <SD.h>

//OneWire on pin 9

OneWire ds(9);

//variables and massives
int HighByte, LowByte, TReading, Tc_100, Whole, Fract, SignBit;
byte i=0,devicenum=0,k=0,j=0,s=0,tempdata[16],address[8],addressmap[10][8];
char* devicetype[10];
File myFile;


//setting up

void setup(void)
{
  Serial.begin(9600);
 
/*while devices appears, i find they addresses and write to a matrix whith 10 strings, so i use up to 10 devises in my programm*/
while (ds.search(address)){
for ( i = 0; i < 8; i++) addressmap[k][i]=address[i];
k=k+1;
}
//remember number of OneWire devices
devicenum = k-1;

/*for each device get a Byte which means type, and write it to another matrix*/
for (k=0; k<=devicenum; k++) {
  switch (addressmap[k][0]) {
  case 16: devicetype[k]="digital thermometer ds1820 (ds1920) series"; break;
  case 32: devicetype[k]="4-channel 16 bit analog->digital converter"; break;
  case 34: devicetype[k]="digital thermometer ds1822"; break;
  case 40: devicetype[k]="digital thermometer ds18b20, up to 12 bit resolution"; break;
  default: devicetype[k]="unknoun 1-Wire device"; break;
                            }
                             }
//print all the addresses and types of devices to a serial
for( k = 0; k <= devicenum; k=k+1) {
Serial.print("Device #"); Serial.print(k); Serial.print(" address is [ ");
  for( i = 0; i < 8; i=i+1) {
    Serial.print(addressmap[k][i], HEX);
    Serial.print(" ");
                            }
    Serial.print(']'); Serial.print(" type of device is "); Serial.println(devicetype[k]);
                                   }
    Serial.println("That's all list of online devices");


 
 Serial.print("Initializing SD card...");
 
 // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
 //   Note that even if it's not used as the CS pin, the hardware SS pin
 //   (10 on most Arduino boards, 53 on the Mega) must be left as an output
 //   or the SD library functions will not work
 
 pinMode(10, OUTPUT);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
 
 // try to open the file
   
  myFile = SD.open("test.txt", FILE_WRITE);
 
  // if ok, then print all the addresses and types of devices to a file:
  if (myFile!=NULL)
  {
    // print to a serial, that i work whith file 
   Serial.println("Writing device mass to test.txt"); 
   
   for( k = 0; k <= devicenum; k=k+1)
  {
    myFile.print("Device #");
    myFile.print(k);
    myFile.print(" address is [ ");
        for( i = 0; i < 8; i=i+1)
        {
         myFile.print(addressmap[k][i], HEX);
         myFile.print(" ");
        }
    myFile.print(']');
    myFile.print(" type of device is ");
    myFile.println(devicetype[k]);
   }
    myFile.println("That's all list of online devices");
            // print to a serial, that i work whith file
   Serial.println("Writing devices data to test.txt"); 
            // series of 12 measurements
   for( s = 0; s < 12; s=s++)
  {
      for( k = 0; k <= devicenum; k=k+1)
    {
      for(i=0;i<8;i++) address[i]=addressmap[k][i]; 
      ds.reset();
      ds.select(address);
      ds.write(0x44,1);         // converting
      delay(1000);              //maybe 750ms is enough
      ds.reset();               // we might do a ds.depower() here, but the reset will take care of it.
      ds.select(address);   
      ds.write(0xBE);         // please, write data to a scratchpad
         for ( j = 0; j < 9; j++) tempdata[j] = ds.read(); // getting 9 Byte data from Scratchpad - page 9 from 27 Datasheet DS18B20
      // we need only 0 and 1 Byte from Scratchpad - page 9 from 27 Datasheet DS18B20
      LowByte = tempdata[0];
      HighByte = tempdata[1];
      TReading = (HighByte << 8) + LowByte;
      SignBit = TReading & 0x8000;  // test most sig bit
    if (SignBit) TReading = (TReading ^ 0xffff) + 1; // if negative, then 2's comp
    Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
    Whole = Tc_100 / 100;  // separate off the whole and fractional portions
    Fract = Tc_100 % 100;
    for (i=0; i<8; i++) myFile.print(address[i],HEX);
      myFile.print("   ");
      myFile.print(tempdata[0],HEX);
      myFile.print("   ");
      myFile.print(tempdata[1],HEX);
      myFile.print('\n');
      myFile.print(" T = ");
     // If its negative
      if (SignBit) myFile.print("-");
      myFile.print(Whole);
      myFile.print(".");
      if (Fract < 10) myFile.print("0");
      myFile.print(Fract);
      myFile.println(" C");
    }
    Serial.println("I'm waiting about 2 sec before next series of measurement");
    delay (2000);
  }
    myFile.close();
    Serial.println("Done.");
  // if the file did not open, writing to a serial error
 
  }
  else Serial.println("error opening test.txt");
}
 void loop(void)
 {

 }
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

     To everyone.
If you guys are interested, in order to thank you, I will describe how I made my cheap micro SD shield with photos and will post it here
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes please!

There are some examples using micro-SD to full size adapter sleeve clear up to old-type floppy drive cable.

Of much interest is going from 5V Arduino to 3.3V SD.
One way is to use 3.3V Arduino!

Best I have seen uses 3.3V supply (different ways of getting that) with pullups and diodes on the signal lines.
When the 5V line is LOW the diode lets current through, the SD pin is LOW.
When the 5V line is HIGH the diode blocks 5V and the 3.3V pullup holds the SD pin 3.3V HIGH.

What I like most with that is the 5V lines are not bleeding current through voltage dividers when they are HIGH.
 
With SD, I went with 1 voltage divider on the power line, change 5V to 3.3V. That same one also powers the pullups.

Sorry about using English. I am typical only know English American. I did take French class but that ended in 1972.
I hope you have friends to help translate and how good it must be not stuck with just one language!
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Pages: [1]   Go Up
Jump to: