Pages: [1]   Go Down
Author Topic: Second time i read dir arduino halts  (Read 1301 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I got my SC Card module working without problems.
In my setup, I use a 4x20 LCD for a menu. In this menu when I select "SC Card", the following sub should run.
And it does first time without any trouble - it shows names of 6 files on my SD Card. But second time it shows names for first 3 files and then get stuck.

Code:
void sdCard() {
  lcd.clear();
  int i=0; int j=0;
  String files [1][3];
  File root; File entry;
  root = SD.open("/");
  do {
    entry =  root.openNextFile();
    lcd.setCursor((j*10)+1, i);
    String ename=entry.name();
    files[j][i]=ename;
    lcd.print(ename.substring(0,ename.indexOf(".")));
    i = i + 1;
    if ((i==4)&&(j==0)) {j=1; i=0;}
  } while ((entry)&&(i+j<5));
  i=0; j=0;
  while (mode==2) {
    lcd.setCursor(j*10, i);
    lcd.print((char)0);     
    if (Button(btnZDown)) {
      while (Button(btnZDown)) {}
      lcd.setCursor(j*10,i);
      lcd.print(" ");
      i = i + 1;
      if (i==4) {
        if (j==1) j=0; else j=1;
        i=0;
      }
      if (files[j][i]=="") {i=0; j=0;}
    }
    if (Button(btnReverse)) {
      while (Button(btnReverse)) {}
      mode=0;
    }
  }
}

void loop() {
  if (Button(btnZDown)) {
    while (Button(btnZDown)) {}
    move_menu_cursor(1);
  }
  if (Button(btnZUp)) {
    while (Button(btnZUp)) {}
    move_menu_cursor(2);
  }
  if (Button(btnReverse)) {
    while (Button(btnReverse)) {}
    mode=menu_cursor;
    if (mode==1) togglemode();
    if (mode==2) sdCard();
    if (mode==3) serialRepeater();
    lcd.clear();
    mainmenu();
  }
}
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 602
Posts: 33362
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When posting code you need to post all of it, so we can spot errors, not just bits of it.
If it is too long then cut it down so that it shows just the errors but post something that compiles and runs and shows the error.
Logged

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

OK Here's the complete sketch:
Trouble's near the bottom.

Code:
/*
 mode 0: Menu
 mode 1: Toggle
 mode 2: SD Card
 mode 3: Serial input
 */

// include the library code:
#include <ShiftRegLCD.h>
#include <SoftwareSerial.h>
#include <SD.h>
#define rxPin 7
#define txPin 8
#define srdataPin 2
#define srclockPin 3

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;

const int chipSelect = 10; 

ShiftRegLCD lcd(srdataPin, srclockPin, TWO_WIRE, 4);
SoftwareSerial mySerial(rxPin, txPin);

float x = 0.000;
float y = 0.000;
float z = 0.000;
int latchPin  = 4;
int clockPin  = 5;
int dataPin  = 6;
int mode = 0;
int menu_cursor = 1;
byte arrow[8] = {16,24,28,30,28,24,16};
int serData;
byte switchVar1 = 72;
int btnYUp =1;
int btnXLeft = 2;
int btnXRight = 3;
int btnYDown = 4;
int btnForward = 5;
int btnReverse = 6;
int btnZDown = 7;
int btnZUp= 8;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.createChar(0, arrow);
  //lcd.begin(40, 4);
  // Print a message to the LCD.
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
 // pinMode(rxPin, INPUT);
 // pinMode(txPin, OUTPUT);
  pinMode(10, OUTPUT);
  SD.begin(chipSelect);
  mainmenu();
}

void mainmenu() {
  lcd.setCursor(0,0);
  lcd.print("MENU");
  lcd.setCursor(0,1);
  lcd.print(" Toggle mode");
  lcd.setCursor(0,2);
  lcd.print(" SD Card");
  lcd.setCursor(0,3);
  lcd.print(" Serial repeater");
  lcd.setCursor(0,menu_cursor);
  lcd.print((char)0);
}

// dir = 1 down dir=0 up
void move_menu_cursor(int dir) {
  if (dir==1) {
    if (menu_cursor<3) {
       menu_cursor ++;
       mainmenu();
    }
  }
  if (dir==2) {
    if (menu_cursor>1) {
       menu_cursor --;
       mainmenu();
    }
  }
}

void togglemode() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Togglemode");
  lcd.setCursor(0,1);
  lcd.print("X: 0.000");
  lcd.setCursor(0,2);
  lcd.print("Y: 0.000");
  lcd.setCursor(0,3);
  lcd.print("Z: 0.000");
  while (mode==1) {

    if (Button(btnZUp)) {
      while (Button(btnZUp)) {}
      z=z+0.100;
    }
    if (Button(btnZDown)) {
      while (Button(btnZDown)) {}
      z=z-0.100;
    }
    if (Button(btnYUp)) {
      while (Button(btnYUp)) {}
      y=y+0.100;
    }
    if (Button(btnYDown)) {
      while (Button(btnYDown)) {}
      y=y-0.100;
    }
    if (Button(btnXLeft)) {
      while (Button(btnXLeft)) {}
      x=x+0.100;
    }
    if (Button(btnXRight)) {
      while (Button(btnXRight)) {}
      x=x-0.100;
    }
    if (Button(btnReverse)) {
      while (Button(btnReverse)) {}
      mode=0;
    }
 
    lcd.setCursor(2,1);
    if (x>=0) {lcd.print(" ");}
    lcd.print(x);
    lcd.setCursor(2,2);
    if (y>=0) {lcd.print(" ");}
    lcd.print(y);
    lcd.setCursor(2,3);
    if (z>=0) {lcd.print(" ");}
    lcd.print(z);
  }
}

void serialRepeater(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Serial repeater");
  Serial.begin(9600);
  Serial.println("Ready ...");
  mySerial.begin(9600);
  mySerial.listen();
  while (mode==3) {   
    while (mySerial.available()) Serial.write(mySerial.read());
    while (Serial.available()) mySerial.write(Serial.read());
    if (Button(btnReverse)) {
      while (Button(btnReverse)) {}
      mode=0;
    }
  } 
}

byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  byte myDataIn = 0;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  for (i=0; i<8; i++)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(20);
    myDataIn = myDataIn << 1;
    myDataIn = myDataIn + digitalRead(myDataPin);
    digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}

boolean getBit(byte myVarIn, byte whatBit) {
  boolean bitState;
  bitState = myVarIn & (1 << (whatBit-1));
  return bitState;
}

boolean Button(byte b) {
  digitalWrite(latchPin,0);
  delayMicroseconds(20);
  digitalWrite(latchPin,1);
  switchVar1 = shiftIn(dataPin, clockPin);
  delayMicroseconds(20);
  return getBit(switchVar1, b);
}

void sdCard() {
  lcd.clear();
  int i=0; int j=0;
  String files [1][3];
  File root; File entry;
  root = SD.open("/");
  do {
    entry =  root.openNextFile();
    lcd.setCursor((j*10)+1, i);
    String ename=entry.name();
    files[j][i]=ename;
    lcd.print(ename.substring(0,ename.indexOf(".")));
    i = i + 1;
    if ((i==4)&&(j==0)) {j=1; i=0;}
  } while ((entry)&&(i+j<5));
  i=0; j=0;
  while (mode==2) {
    lcd.setCursor(j*10, i);
    lcd.print((char)0);     
    if (Button(btnZDown)) {
      while (Button(btnZDown)) {}
      lcd.setCursor(j*10,i);
      lcd.print(" ");
      i = i + 1;
      if (i==4) {
        if (j==1) j=0; else j=1;
        i=0;
      }
      if (files[j][i]=="") {i=0; j=0;}
    }
    if (Button(btnReverse)) {
      while (Button(btnReverse)) {}
      mode=0;
    }
  }
}

void loop() {
  if (Button(btnZDown)) {
    while (Button(btnZDown)) {}
    move_menu_cursor(1);
  }
  if (Button(btnZUp)) {
    while (Button(btnZUp)) {}
    move_menu_cursor(2);
  }
  if (Button(btnReverse)) {
    while (Button(btnReverse)) {}
    mode=menu_cursor;
    if (mode==1) togglemode();
    if (mode==2) sdCard();
    if (mode==3) serialRepeater();
    lcd.clear();
    mainmenu();
  }
}
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 602
Posts: 33362
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When you include code can you include a link to the libraries you used otherwise no one else can compile the code.
Logged

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

Oh, you are of course missing ShiftRegLCD.h. It's makes it possible to run LCD's with only two digital pins.

Info here: http://code.google.com/p/arduinoshiftreglcd/

Code here: http://arduinoshiftreglcd.googlecode.com/files/ShiftRegLCD_2012.02.15.tar.gz
Logged

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

Here's a little more information:

SD Card Module is this one: http://i01.i.aliimg.com/img/pb/535/556/434/434556535_986.jpg
LCD is like this one: http://i.ebayimg.com/t/Arduino-4-Line-LCD-20x4-Character-LCD-Module-with-Blue-Backlight-/00/s/MjI3WDQwMA==/$(KGrHqR,!lIE+25mSk!TBQSm(jZUqw~~60_12.JPG
I use a Arduino Uno R2 .
My buttons use a shift register 74HC165.
This is a picture of my project in an earlier state: http://letsmakerobots.com/files/userpics/u19240/Arduino2wirelcd.jpg
Logged

0
Online Online
Edison Member
*
Karma: 63
Posts: 1603
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There are several problems.  The most serious is
Code:
String files [1][3];
may used with bad indicies here:
Code:
    files[j][i]=ename;
It looks like j could be one and i could be three.

Another problem is that the File wrapper for SdFat uses malloc so this assignment causes a memory leak unless you close entry. 
Code:
    entry =  root.openNextFile();
I didn't write the SD.h wrapper so you you nee to post this problem on the Arduino issues site.

There are other problems like you using the SD object and Sd2Card and SdVolume.  SD already has an instance of Sd2Card and SdVolume.

I stopped looking after I found these problems.
Logged

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

Thank you for the answers. I appreciate.
But I would very much like to understand the answers to.

My intentions in the code are:
Declare an two dimensional array of stings to hold up 8 file names.
Code:
String files [1][3];
Then fill this array by counting i from 0 to 3 and j from 0 to 1 in this loop:
Code:
  do {
    entry =  root.openNextFile();
    lcd.setCursor((j*10)+1, i);
    String ename=entry.name();
    files[j][i]=ename;
    lcd.print(ename.substring(0,ename.indexOf(".")));
    i = i + 1;
    if ((i==4)&&(j==0)) {j=1; i=0;}
  } while ((entry)&&(i+j<5));
So yes j could be one and i could be three. That's the idea.
It also seems that after the first completion of this loop, the array is filled as intended.
The values are now selectable and I can move a cursor around. This code:
Code:
if (files[j][i]=="") {i=0; j=0;}
... is checking if an item is empty and if so jump's to the first item. Really works as intended, but only first time I run the sub.

So what is wrong.
I declare the array inside the sub to make it local. In this way I hope the memory is cleared after getting out of scope. Is this my mistake?
Some has mentions that there could be issues with String-objects. But I cant find anything explicit about this. Could such issues play a role here?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 602
Posts: 33362
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So yes j could be one and i could be three. That's the idea.
in which case you have not declaired the array to be big enough.
Array indexes start at zero, but array sizes are just that sizes. Therefore for an array with eight spaces in it you need to declaire it as
Code:
String files [2][4];
« Last Edit: November 25, 2012, 04:01:32 am by Grumpy_Mike » Logged

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

Thanks Grumpy Mike, that hit the spot. It's just me being a total c-ignorant smiley-grin.
Thanks a lot. Now it works like a dream.
A lesson learnt, an error forever to be repeated. smiley-mr-green
Logged

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

I still got a problem.

Quote
Another problem is that the File wrapper for SdFat uses malloc so this assignment causes a memory leak unless you close entry

How do I close these, they have no close-method.
Logged

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

Sorry, they got a close method.

Quote
How do I close these, they have no close-method.

But using it course more problems. I made "root" and "entry" global and I'm trying to tidy up before leaving sub.
Logged

Pages: [1]   Go Up
Jump to: