Show Posts
Pages: [1] 2
1  Using Arduino / Storage / Re: Class 10 uSD card is slower than class 6 with SdFat library? on: April 04, 2011, 07:43:30 am
There's always more to it than I think... Thank you very much!
2  Using Arduino / Storage / Class 10 uSD card is slower than class 6 with SdFat library? on: March 18, 2011, 11:47:46 am
I'm using the SdFat library from Bill Gre...(i forget) and it is working nicely. I got a class 10 Patriot 4 GB uSDHC card to see if it would decrease the write time as opposed to my Transcend class 6 1 GB uSD card, but it certainly does not. When formatted as FAT32 like it should be, the library gives me all sorts of errors. When I format it as FAT16, it takes 4 times as long as the class 6 card.
Any thoughts?
Thanks!
3  Using Arduino / Storage / Re: Got SD card working, but stable setup? on: March 18, 2011, 11:44:44 am
Its great that it works, but I'm a bit skeptical of whether its good for the SD card. It seems like it would be giving an overvoltage to to CS MOSI and SCLK lines when they are high. As far as I know SD cards don't like it very much when they see over 3.5V, so if you can measure it at the SD card and its below that, then great! But my instinct tells me it would be higher...
4  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 02:10:05 pm
Brilliant! Thank you!
5  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 01:56:45 pm
I'll admit, that is something I'm a bit fuzzy on. Would
Code:
void setRegister(int reg, boolean highOrLow, byte whichBits[], byte setTo[]) { 
declare it as an array, giving me the number of items in the array with sizeof()?

Also, I just removed all the Serial.print statements from the setRegister() function... and it seems to do the trick!!! That is not something I would have ever thought of. Do you have any insight on why that causes the hang up?
6  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 01:49:08 pm
Interesting catch. I thought sizeof() gave you the number of bytes in whatever argument you provide. So if I use
Code:
byte whichBits[] = {2,1,0};
wouldn't
Code:
byte n=sizeof(whichBits);
return 3, since whichBits has three 1-byte values in it?
7  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 01:37:52 pm
And here is all the other functions with the setRegister() function at the bottom.
Code:


void isr() {
  readAllToString();
  samplecounter++;
  // This check will skip the block if the SD
  //    card is not done writing
  if(samplecounter==samples_per_block){
    strlcpy((char*)pCache,(char*)dataString,samples_per_block*sample_size+1);
  }
}



//Sends a read command to the ADIS16367:
int readRegister(byte thisRegister ) {
  int result = 0;   // result to return
  bitClear(PORTD,chipSelectPin);
  // ADIS16367 expects the register address in the lower 7 bits
  // now combine the register address and the command into one byte:
  byte dataToSend = thisRegister | READ;
  // take the chip select low to select the device:
  while(bitRead(PIND,dataReadyPin));
  //  while(digitalRead(dataReadyPin)); //Wait if the pin is low
  // send the device the register you want to read: 
  SPItransfer2(dataToSend,0);
  delayMicroseconds(4);
  result = SPItransfer2(0,0);
  bitSet(PORTD,chipSelectPin);
  // return the result:
  return(result);
}


void writeRegister(byte reg, byte data) {
  bitClear(PORTD,chipSelectPin);     // Select device
  SPItransfer2(reg|WRITE,data);      // Writes data to register
  bitSet(PORTD,chipSelectPin);       // Deselect device
}


// Transfer 2 bytes via SPI and combine the results
// into a 16 bit int
int SPItransfer2(byte data1, byte data2) {
  int result = SPItransfer(data1)<<8;
  result |= SPItransfer(data2);
  return(result);
}

// Transfer a single byte via SPI
byte SPItransfer(byte data) {
  // SCK begins high
  for(byte bit=0 ; bit<8 ; bit++) {
    bitClear(PORTD,sclkPin); // SCK fall low
    bitWrite(PORTD,mosiPin,(data>>7) & 0x01); // Write data to MOSI pin
    data = data << 1;
    bitSet(PORTD,sclkPin); // SCK rise high
    data |= bitRead(PIND,misoPin); // read data from MISO pin
  }
  return(data);
}



// Read all registers and write to string
// String begins with new line (0-1)
// Time takes 6 hex chars (2-7)
// Each of gyro/acc takes 4 hex chars, 14 bits (8-11,12-15,16-19...8+i*5-8+i*5+3)
// Auxilary ADC takes 3 hex chars, 12 bits (39-41)
void readAllToString(void) {
  // take the chip select low to select the device
  bitClear(PORTD,chipSelectPin);
  //Wait if the pin is low
  while(bitRead(PIND,dataReadyPin));
  addhexchar(dataString, millis(), 2 + (samplecounter*sample_size),6);
  // Get time and write to string
  SPItransfer2(XGYRO_OUT,0); // Ask for X Gyro
  int data = SPItransfer2(YGYRO_OUT,0); // Get X Gyro and ask for Y Gyro
  addhexchar(dataString, data&0x3FFF, 9+(0*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(ZGYRO_OUT,0);     // Get Y Gyro and ask for Z Gyro
  addhexchar(dataString, data&0x3FFF, 9+(1*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(XACCL_OUT,0);     // Get Z Gyro and ask for X Acc
  addhexchar(dataString, data&0x3FFF, 9+(2*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(YACCL_OUT,0);     // Get X Acc and ask for Y Acc
  addhexchar(dataString, data&0x3FFF, 9+(3*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(ZACCL_OUT,0);     // Get Y Acc and ask for Z Acc
  addhexchar(dataString, data&0x3FFF, 9+(4*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(AUX_ADC,0);       // Get Z Acc and ask for Aux ADC
  addhexchar(dataString, data&0x3FFF, 9+(5*5) + (samplecounter*sample_size),4);
  // Save to text string
  data = SPItransfer2(0,0);             // Get Aux ADC
  addhexchar(dataString, data&0xFFF, 39 + (samplecounter*sample_size),3);
  // Save to text string
  // Pull chip select HIGH to delect
  bitSet(PORTD,chipSelectPin);
}




void SPIbegin(byte CSpin) {
  // Set correct pin modes
  pinMode(dataReadyPin, INPUT);
  pinMode(CSpin, OUTPUT);
  pinMode(mosiPin,OUTPUT);
  pinMode(misoPin,INPUT);
  pinMode(sclkPin,OUTPUT);
  //Clock polarity in mode 3 is high
  digitalWrite(sclkPin,HIGH);
  //Set chip select low to activate device
  digitalWrite(CSpin, HIGH);
}



// creates char[] from int in hex with digits chars
void addhexchar(volatile char* c, unsigned long n, int start, int digits)
{
  byte nextchar;
  for(int ii=0; ii<digits ; ii++) {
    nextchar = (n >> (digits-ii-1)*4) & 0xf;
    if(nextchar<=9) {
      c[start+ii] = '0' + nextchar;
    }
    else {
      c[start+ii] = 'A' + nextchar-10;
    }
  }
}



// Sends commands to set a given register
void setRegister(int reg, boolean highOrLow, byte* whichBits, byte* setTo) { 
  byte n=sizeof(whichBits);
  delay(500);
  // Read in data from register
  int regdata;
  if(highOrLow==HIGH) {
    regdata = highByte(readRegister(reg));
  }
  else {
    regdata = lowByte(readRegister(reg));
  }
  Serial.print("Register contains: ");Serial.println(regdata,BIN);
 
  // Set or clear bits as needed
  byte working = regdata;
  for (int ii=0 ; ii<n ; ii++) {
    if(setTo[ii]==1) {
      bitSet(working,whichBits[ii]);
    }
    else {
      bitClear(working,whichBits[ii]);
    }
  }
  Serial.print("Writing: ");Serial.println(working,BIN);
 
  //Write to register
  if(working!=regdata) {
    writeRegister(reg+highOrLow,working);
  }
  else {
    Serial.println("Register already set correctly");
  }
  delay(100);
  asdf
  //Check if it's right!
  regdata = readRegister(reg);
  if(highOrLow==HIGH) {
    regdata = highByte(regdata);
  }
  else {
    regdata = lowByte(regdata);
  }
 
  if(regdata==working) {
    Serial.println("Successful");
  }
  else {
    Serial.print(regdata,BIN);
    Serial.println(" fail...");
  }
  delay(500);
}

8  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 01:37:12 pm
That was the header stuff and the setup()

Here is the loop()
Code:
void loop() {
  char nextchar;
  // Look for configuration file
  if (configfile.open(&root, "CONFIG.TXT", O_READ)) {
    Serial.println("Reading configuration file...");

    delaytime = 0;
    nextchar = configfile.read();
    while(nextchar>='0' && nextchar<='9') {
      delaytime = delaytime*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    while(nextchar<='0' || nextchar>='9') {
      nextchar = configfile.read();
    }


    fs = 0;
    while(nextchar>='0' && nextchar<='9') {
      fs = fs*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    while(nextchar<='0' || nextchar>='9') {
      nextchar = configfile.read();
    }


    time = 0;
    while(nextchar>='0' && nextchar<='9') {
      time = time*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    configfile.close();
  }
  else if(configfile.open(&root, "config.txt", O_READ)) {
    Serial.println("Reading configuration file...");

    delaytime = 0;
    nextchar = configfile.read();
    while(nextchar>='0' && nextchar<='9') {
      delaytime = delaytime*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    while(nextchar<='0' || nextchar>='9') {
      nextchar = configfile.read();
    }


    fs = 0;
    while(nextchar>='0' && nextchar<='9') {
      fs = fs*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    while(nextchar<='0' || nextchar>='9') {
      nextchar = configfile.read();
    }


    time = 0;
    while(nextchar>='0' && nextchar<='9') {
      time = time*10 + (nextchar-'0');
      nextchar = configfile.read();
    }
    configfile.close();
  }
  else {
    Serial.println("No CONFIG.TXT found, using default values");
  }

  // Display recording data
  Serial.print("delay time (s) = ");
  Serial.println(delaytime);
  Serial.print("fs (sps) = ");
  Serial.println(fs);
  Serial.print("time (s) = ");
  Serial.println(time);
  Serial.print("sample size (chars) = ");
  Serial.println(sample_size);
  Serial.print("samp/block = ");
  Serial.println(samples_per_block);
  unsigned int block_count = (fs*time)/samples_per_block;
  Serial.print("blocks = ");
  Serial.println(block_count);

  // Begin Delay
  Serial.println("Beginning delay...");
  delay(delaytime*1000);
  Serial.println("Delay completed");

  // Send command to set gyro range to +/- 1200 deg/s
  Serial.println("Set range to +/- 1200 deg/s");
  byte whichBits[] = {2,1,0};
  byte setToWhat[] = {1,0,0};
//  setRegister(SENS_AVG,HIGH,whichBits,setToWhat);
//  Serial.println("Set Bartlett filter to 4 taps");
//  setRegister(SENS_AVG,LOW,whichBits,setToWhat);
  Serial.println("Configuration Complete!");
 
 
  // Set up file to write
  char filename[] = "DATA00.TXT";
  byte filenum = 0;
  while (file.open(&root, filename, O_READ)) {
    file.close();
    filenum++;
    filename[4] = (filenum/10)+'0';
    filename[5] = (filenum%10)+'0';
  }


  // Create a contiguous file
  if (!file.createContiguous(&root, filename, 512UL*block_count)) {
    error_P(PSTR("createContiguous failed"));
  }
  // Get the location of the file's blocks
  if (!file.contiguousRange(&bgnBlock, &endBlock)) {
    error_P(PSTR("contiguousRange failed"));
  }
  //*********************NOTE**************************************
  // NO SdFile calls are allowed while cache is used for raw writes
  //***************************************************************

  // Clear the cache and use it as a 512 byte buffer
  //  uint8_t* pCache = volume.cacheClear();
  pCache = volume.cacheClear();

  // Fill cache with samples_per_block lines
  for(int i = 0 ; i<512 ; i++) {
    dataString[i] = ' ';
    pCache[i] = ' ';
  }
  // Loop through each sample
  for (int i = 0 ; i < 512-sample_size; i += sample_size) {
    // And put newline/carriage return at end of line
    dataString[i] = '\r';
    dataString[i+1] = '\n';
  }
  dataString[511] = '\0';   //EOF end of file character must end each string
  pCache[511] = '\0';   //EOF end of file character must end each string



  Serial.print("Start raw write of ");
  Serial.print(file.fileSize());
  Serial.println(" bytes at");

  Serial.print((512UL*block_count)/time);
  Serial.println(" bytes per second");

  Serial.print("to ");
  Serial.println(filename);

  Serial.print("Please wait ");
  Serial.print(time);
  Serial.println(" seconds");

  // tell card to setup for multiple block write with pre-erase
  if (!card.erase(bgnBlock, endBlock)) error_P(PSTR("card.erase failed"));
  if (!card.writeStart(bgnBlock, block_count)) {
    error_P(PSTR("writeStart failed"));
  }

  // Init stats
  unsigned int maxWriteTime = 0;
  unsigned long start = millis();
  unsigned long writeTime = 0;

  // Start Timer1
  Timer1.initialize((1000000UL/fs)); // Start timer at fs Hz
  // Attach timer interrupt
  Timer1.attachInterrupt(isr);

  while( (millis()-start) < (time*1000) ) {
    if (samplecounter==samples_per_block) {
      samplecounter = 0;
      // Write a 512 byte block
      writeTime = micros();
      if (!card.writeData(pCache)) {
        error_P(PSTR("writeData failed"));
        while(1);
      }
      writeTime = micros() - writeTime;
      // Check for max write time
      if (writeTime > maxWriteTime) {
        maxWriteTime = writeTime;
      }
    }
  }

  // Stop the interrupt
  Timer1.detachInterrupt();

  // End multiple block write mode
  if (!card.writeStop()) error_P(PSTR("writeStop failed"));

  Serial.println();
  Serial.println("Done");

  Serial.print("Elapsed time: ");
  Serial.print(millis()-start);
  Serial.println(" millis");

  Serial.print("Max write time: ");
  Serial.print(maxWriteTime);
  Serial.println(" micros");

  // Close files for next pass of loop
  root.close();
  file.close();
  Serial.println();

  // All done, stop here
  while(1);
}

9  Using Arduino / Programming Questions / Re: Uncalled function stops program from running? on: March 10, 2011, 01:36:10 pm
Good hint...

Here is the sketch in its entirety (continued in next post). The function causing the problem is setRegister(), at the very bottom. I am looking to call this in the loop(), but it is commented out now.

Code:
/*
 ADIS 16367 Logger
 
 Creates bit-banged SPI implementation for ADIS16367
 This is able to use readAllToString() which reads
 data from sensor, writes to string, and prints it
 once the buffer has been filled
 
 It does so using an interrupt triggered by Timer1
 
 Writes to SD card once there has been a sufficient
 number of samples to fill the buffer.
 
 It requires a file CONFIG.TXT to exist in the root
 directory of the SD card. It must contain 3 numbers
 the delay time (s), sampling frequency (1/s), and
 recording time (s) in that order. All other characters
 in the file are ignored.
 
 Circuit:
 Arduino          ->   ADIS 16367
 IRQ: pin 4         ->  DIO1: pin 7
 CS: pin 7          ->  CS: pin 6
 DI/MOSI: pin 3     ->  DIN: pin 5
 DOUT/MISO: pin 5   ->  DOUT: pin 4
 SCLK: pin 2        ->  SCLK: pin 3
 
 Arduino          ->    SD Card
 MOSI: pin 11       ->  DI
 MISO: pin 12       ->  DO
 SCK: pin 13        ->  SCK
 CS: pin 10         ->  CS
 
 created 22 Feb 2011
 modified 22 Feb 2011
 by Matt Harding
 
 Thank you to:
 Bill Greiman for his SdFat library
 http://code.google.com/p/sdfatlib/
 Jesse Tane for the Timer1 library
 http://perfectverse.com/jesse/portfolio/projects/timerOne/index.html
 Sebastian Tomczak for his "SPI by Hand" example
 http://little-scale.blogspot.com/2007/07/spi-by-hand.html
 */

#include <SdFat.h>
#include <SdFatUtil.h>
#include "TimerOne.h"

unsigned int fs = 10;
unsigned long time = 5;
const unsigned int sample_size = 42;
unsigned int samples_per_block = 512/sample_size;
unsigned long delaytime = 5;

// counters and data strings
volatile unsigned int samplecounter = 0;
volatile unsigned int counter = 0;

// data strings
volatile char dataString[512];
uint8_t* pCache;

// IMU pins
const byte dataReadyPin = 4;
const byte chipSelectPin = 7;
const byte mosiPin = 3;
const byte misoPin = 5;
const byte sclkPin = 2;
const byte SDcs = 10;


Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
SdFile configfile;

uint32_t bgnBlock, endBlock;

//// store error strings in flash to save RAM
//#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  Serial.print("error: ");
  Serial.println(str);
  if (card.errorCode()) {
    Serial.print("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

//Sensor's memory register addresses:
const byte SUPPLY_OUT = 0x02;    // Power supply reading
// a bunch of defines are omitted hereā€¦

//Sensor commands
const byte READ = 0b00000000;     // ADIS16367 read command (2 bytes)
const byte WRITE = 0b10000000;   // ADIS16367 write command
const byte BURST_READ = 0x3E;  // ADIS16367 burst read command

void setup() {
  // Setup communications
  Serial.begin(115200);

  Serial.flush();
  Serial.println("Type any character to start");
  while (!Serial.available());

  // Initialize ADIS SPI bus
  SPIbegin(chipSelectPin);

  // Initialize SD card
  unsigned long start = millis();

  pinMode(SDcs, OUTPUT);
  digitalWrite(SDcs, LOW);
  // initialize the SD card at SPI_FULL_SPEED for best performance.
  // try SPI_HALF_SPEED if bus errors occur.
  if (!card.init(SPI_FULL_SPEED)) error_P(PSTR("card.init failed"));

  start = millis() - start;

  Serial.print("Card init time: ");
  Serial.print(start);
  Serial.println(" millis");

  // initialize a FAT volume
  if (!volume.init(&card)) error_P(PSTR("volume.init failed"));

  // open the root directory
  if (!root.openRoot(&volume)) error_P(PSTR("openRoot failed"));
}
10  Using Arduino / Programming Questions / Uncalled function stops program from running? on: March 10, 2011, 01:05:30 pm
I am running into a strange problem...

I have a working code to read a sensor and write to an SD card. Now I want to write something to a register on the sensor, so I wrote a function that should do so. HOWEVER, with that function in the code, even when the function is not called at all, the program executes the first few lines of code in setup() and returns back to the first line!?

I am baffled at why this additional function, which is not called within setup() or loop() at all would cause the program to act differently. Help please?

Thanks
11  Using Arduino / Microcontrollers / Pull 3.3V from Pro Mini regulator? on: March 05, 2011, 10:56:18 am
I'm wondering if I power the Arduino Pro Mini 3.3V with a raw voltage (9V, say) can the regulator power the Arduino and allow me to draw current to power an SD card socket from the Vcc pin? An SD card needs 50-100 mA at 3.3V. Anyone tried it?
12  Using Arduino / Programming Questions / Re: Copy a char array? on: February 25, 2011, 03:58:01 pm
Interesting...

so it seems like if I were to make a function such as
Code:
void copyStrings(uint8_t* to, volatile uint8_t from, int n) {
  for(int ii=0 ; ii<n ; ii++) {
    to[ii] = from[ii];
  }
}

of
Code:
void copyStrings(char *dst, const char *src)
{
while (*to++ = *from++) ;
}

it would probably be less computationally efficient?
13  Using Arduino / Programming Questions / Re: Copy a char array? on: February 25, 2011, 03:38:41 pm
Thanks for the reply. It seemed like that would be a good function to use, but since I have to cast both of the arguments, does that take more time?

And pCache does point to enough space to hold all 512 bytes. I'm using it now and it works, it just takes more time than I would like.
14  Using Arduino / Programming Questions / Copy a char array? on: February 25, 2011, 03:16:59 pm
Hello,

I'm trying to copy the contents of one array
Code:
volatile uint8_t dataString[512];
into another array
Code:
uint8_t* pCache=volume.cacheClear();
dataString is a volatile because it is being changed in an interrupt.
pCache is made using the SdFat library by Bill Greiman.
Right now I am using the following call to copy them
Code:
strlcpy((char*)pCache,(char*)dataString,512);
This probably isn't the best way to do it... and I'm trying to make sure this goes very fast.
Any thoughts?

Thanks!
15  Using Arduino / Networking, Protocols, and Devices / Bit-bang SPI... kind of works? on: February 21, 2011, 11:04:03 am
I'm working on creating a bit-banged SPI implementation on an Arduino Pro Mini 3.3V 8MHz. I must dedicate the hardware SPI bus to another device, but want to communicate with another SPI sensor (Analog Devices ADIS16367 IMU).

It uses SPI Mode 3 (clock polarity = 1, clock phase  = 1) and I created the simple code below. When I want to read a register, it returns some value, but it is not correct.

When I want to read something such as the Product ID, I always receive the same value, as I should, but it is not the correct value.

When I want to read something such as an accelerometer, I always receive fluctuating values, as I should because of the signal noise, but it is also not a correct value.

Anyone have any thoughts?
Thanks!

Code:
//Sends a read command to the ADIS16367:
int readRegisterInt(byte thisRegister ) {
  int result = 0;   // result to return
  // ADIS16367 expects the register address in the lower 7 bits
  // now combine the register address and the command into one byte:
  int dataToSend = ((int)thisRegister<<8)&0xFF00;
  while(digitalRead(dataReadyPin)); //Wait if the pin is low
  // send the device the register you want to read: 
  spiIntTransfer(dataToSend);
  result = spiIntTransfer(0x0000);
  // return the result:
  return(result);
}


int spiIntTransfer(int data) {
  // SCK begins high
  for(byte bit=0 ; bit<16 ; bit++) {
    digitalWrite(sclkPin,LOW); // SCK fall low
    digitalWrite(mosiPin, (data>>15) & 0x0001); // Write data to MOSI pin
    data = data << 1;
    digitalWrite(sclkPin,HIGH); // SCK rise high
//    data |= digitalRead(misoPin); // read data from MISO pin
//    Serial.print(bitRead(PIND,5),BIN);
    data |= bitRead(PIND,misoPin); // read data from MISO pin
  }
  return(data);
}
Pages: [1] 2