Show Posts
Pages: 1 ... 57 58 [59] 60 61 ... 99
871  Development / Suggestions for the Arduino Project / Re: String corrupts the heap and crashes on: July 23, 2012, 01:57:09 pm
The bug is really ugly since the String calls complete successfully but the heap has been destroyed.  The crash often happens in some other part of the program much later.

I looked at String and thought about modifying it with traps like PaulS suggested but soon realized there are lots more things to check.

I decided finding bugs in String is above my pay grade.

Besides, I was trained to never use the heap/malloc in embedded systems.  Most coding standards for critical aerospace systems http://www2.research.att.com/~bs/JSF-AV-rules.pdf and motor vehicle coding standards like MISRA have statements like this:
Quote
MISRA C++ rule 18-4-1, dynamic heap memory allocation cannot be used.
872  Development / Suggestions for the Arduino Project / String corrupts the heap and crashes on: July 23, 2012, 11:50:37 am
This example, which crashes before printing "Done", demonstrates a serious bug in String.
Code:
#include <MemoryFree.h>
void setup() {
  Serial.begin(9600);
}
void loop() {
  int n = 0;
  while(n <=100) {
    int u = 20*n;
    int v = 30*n;
    String str = String(n) + ", " + String(u) + ", " + String(v) + ", " + String(freeMemory());
    Serial.println(str);
    delay(500);
    n++;
  }
  Serial.println("Done"); 
}
The output looks like this and the value of freeMemory() in the last column indicates a corrupt heap.
Quote
0, 0, 0, 1740
1, 20, 30, 1738
2, 40, 60, 13048
3, 60, 90, 24358
4, 80, 120, -29870
5, 100, 150, -17536
6, 120, 180, -3921
7, 140, 210, 10462
8, 160, 240, 23054
9, 180, 270, -29122
-----crash and restart here---

The bug is from a larger program here http://arduino.cc/forum/index.php/topic,115451.0.html
873  Using Arduino / Storage / Re: Data Logger SD, String stops earlier than expected on: July 23, 2012, 09:43:15 am
Looks like String corrupts the heap.  I added freeMemory() to a simplified version of the program and the result makes no sense.  The problem seems to be with the free list.

Here is the simple program that fails:
Code:
#include <MemoryFree.h>
void setup() {
  Serial.begin(9600);
  Serial.println(freeMemory());
}

void loop() {
  int id = 0;
  while (id <= 20)
  {
    //Main battery Voltage
    int voltage = 20*id;  //analogRead(1);
    //Sense Resistance/ Current Drawn
    int current = 30*id;  //analogRead(2);

    //Create Data string for storing to SD card 
    String dataString = String(id)+ ", " +String(voltage)+", "+ String(current)+", "+String(freeMemory());

    Serial.println(dataString);
    //Increment ID number
    id++;
    delay(500);
  }
}

Here is the printout.  The last column is the value returned by freeMemory() which is nonsense.
Quote
0, 0, 0, 1742
1, 20, 30, 1740
2, 40, 60, 13050
3, 60, 90, 24360
4, 80, 120, -29868
5, 100, 150, -17534
6, 120, 180, -3919
7, 140, 210, 10464
8, 160, 240, 23056
9, 180, 270, -29120
If I comment out this line in freeMemory
Code:
//    free_memory += freeListSize();
I get this
Quote
1828
0, 0, 0, 1742
1, 20, 30, 1703
2, 40, 60, 1703
3, 60, 90, 1703
4, 80, 120, 1703
5, 100, 150, 1703
6, 120, 180, 1703
7, 140, 210, 1703
8, 160, 240, 1703
9, 180, 270, 1703
So a bug in String must write over the free list.
874  Development / Other Software Development / Re: Fast digital I/O and software SPI with C++ templates on: July 21, 2012, 06:34:29 pm
FastDigitalIO has evolved into DigitalPin http://arduino.cc/forum/index.php/topic,86931.0.html.

You must use constant pin numbers with any of the fast digital I/O libraries.  That's the only way the compiler can optimize to the fast sbi and cbi instructions.  This means you may need to use templates to use a fast I/O library in another library.

I will include an example software SPI library based on DigitalPin in the next version of DigitalPin.

I am using DigitalPin and SoftSPI in the 20120719 version of SdFat http://code.google.com/p/sdfatlib/downloads/list. The files for DigitalPin and SoftSPI are in the utility folder of SdFat.  I will soon post these files as a standalone library.
875  Development / Other Software Development / Re: Fast alternative to digitalRead/digitalWrite on: July 21, 2012, 01:47:40 pm
I can't improve the speed since functions like pin.high() and pin.low() compile to a single sbi or cbi instruction for low address I/O ports.  All ports on the 328 and ports A-G on the Mega are low address.  These instructions execute in 2 cycles or 125 ns on a 16 MHz cpu.

I have added software SPI which runs at about 2 MHz.  This library supports all SPI modes for MSB first.  It would be easy to add an option for LSB first.

I have not posted the latest version as a standalone library.  The latest version of DigitalPin with SoftSPI is used in the new 20120719 version of SdFat.  The files DigitalPin.h and SoftSPI.h are in the SdFat/utility folder and SdFat is here http://code.google.com/p/sdfatlib/downloads/list.

I have also written a software I2C library based on the DigitalPin library that runs at 400 kHz.  I plan to post this I2C library soon.
876  Using Arduino / Storage / Re: SdFat update on: July 21, 2012, 09:13:11 am
SdFat has a function, rmRfStar(), that will clean an SD.  Here is the documentation:
Quote
bool SdBaseFile::rmRfStar()    

Recursively delete a directory and all contained files.

This is like the Unix/Linux 'rm -rf *' if called with the root directory hence the name.

Warning - This will remove all contents of the directory including subdirectories. The directory will then be removed if it is not root. The read-only attribute for files will be ignored.

Note:
    This function should not be used to delete the 8.3 version of a directory that has a long name.

Returns:
    The value one, true, is returned for success and the value zero, false, is returned for failure.

Here is an example sketch that will delete all except the root directory:
Code:
#include <SdFat.h>
SdFat sd;

void setup() {
  Serial.begin(9600);
  Serial.println("Type any character to delete all files");
  while (Serial.read() <= 0) {}
  if (!sd.begin()) sd.initErrorHalt();
  // list all files
  sd.ls(LS_R);
  // sd.vwd() is root, working directory for volume
  // remove all files and directories in root
  sd.vwd()->rmRfStar();
  Serial.println("---------- rmRfStar()");
  sd.ls(LS_R);
  Serial.println("Done");
  }
void loop() {}
Here is output from the sketch using an SD with two directories and a file.
Quote
Type any character to delete all files
DIR2/
  DIR3/
    NAME3.TXT
---------- rmRfStar()
Done

877  Using Arduino / Storage / Re: SdFat.h incompatible with SD.h? on: July 20, 2012, 09:26:01 am
If you mean file.available(), SdFat does not provide available() since this function does not always provide the correct result in SD.h. The problem is available() is declared as an int in the Stream class.  Type int is limited to 32767 bytes but files can be much larger, up to 4294967295 bytes.

You can use the following expression in SdFat:
Code:
 uint32_t bytesLeft;
  bytesLeft = file.fileSize() - file.curPosition();

Too get the correct result with SD.h use this expression instead of available():
Code:
 uint32_t bytesLeft;
  bytesLeft = file.size() - file.position();

878  Using Arduino / Storage / Re: SD card file write is skipping data on: July 20, 2012, 09:12:14 am
SD.begin() initializes the SD card, mounts the FAT volume, and clears any unwritten data in internal buffers.

Calling it in loop discards a lot of data and may cause file system corruption.  SD.h was not designed to call SD.begin() multiple times.  SD.h is a wrapper for an old version of SdFat.  The wrapper has bugs that prevent multiple calls from always working.

SdFat allows multiple calls to begin/init if all files are closed first.  This allows one SD card to be removed and another SD card to be inserted.
879  Using Arduino / Storage / SdFat update on: July 19, 2012, 04:23:35 pm
A new version of SdFat, sdfatlib20120719.zip, is available here http://code.google.com/p/sdfatlib/downloads/list.

This version requires Arduino version 1.0 or greater since implementing and testing new features in older versions is time consuming and messy.

Here are some of the additions/changes:
Quote
Added support for SDXC cards formatted as FAT32.  Modified the SdFormatter
example to format SDXC cards as FAT32.  This is not the SDXC standard which
is exFAT.

Added Arduino style SdFat::begin(chipSelect, spiSpeed);

Added options for SD crc checking.  Enabling crc checking increases reliability
at the cost of speed.  Edit SdFatConfig.h to select CRC options.

Added << operator for Arduino flash string macro F().

New RawWrite example for fast write of contiguous files.

New faster software SPI

Software SPI for Leonardo boards

Changes to allow use of the SerialPort library.

Error messages and output from programs are now sent to a stdOut Print
stream.

The default stdOut is a small non-interrupt driven class that outputs messages
to serial port zero.  This allows an alternate Serial library like SerialPort
to be used with SdFat.

You can redirect stdOut with SdFat::setStdOut(Print* stream) and
get the current stdOut stream with SdFat::stdOut().

Change file type for all examples to *.ino.

Removed __cxa_pure_virtual to avoid conflicts with other libraries.
880  Using Arduino / Storage / Re: Need help connecting CH375B USB module to Arduino Mega 2560 on: July 19, 2012, 06:45:11 am
You can't connect the module until you know what hardware configuration the software expects. 
881  Using Arduino / Storage / Re: Need help connecting CH375B USB module to Arduino Mega 2560 on: July 18, 2012, 01:34:06 pm
This is not an easy device to write software for.  Is there any software available for the Arduino?   How do you plan to use it?

The connection will depend on what is required by the software.

This module need to have it's data pins D0-D7 connected to a 8-bit port.  pins on Port A or C on the Mega might work.

INT, CS, A0, RD, and WR need to be connected to other pins.

882  Using Arduino / Programming Questions / Re: Adding leading zeros to HEX on: July 16, 2012, 08:19:57 pm
I second TCWORLD's opinion that sprintf is almost always a better solution to formatting than the String class.  I like snprintf a little better since it is safer but in this case you will never overflow the character array.

In addition to being simpler the sprintf solution takes less memory.  This sketch takes 4070 bytes and has no zero fill.
Code:
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  String dataString = "";
  dataString += String(mac[0], HEX);
  dataString += ":";
  dataString += String(mac[1], HEX);
  dataString += ":";
  dataString += String(mac[2], HEX);
  dataString += ":";
  dataString += String(mac[3], HEX);
  dataString += ":";
  dataString += String(mac[4], HEX);
  dataString += ":";
  dataString += String(mac[5], HEX);
  Serial.println(dataString);
}
void loop() {
}
This sketch takes 3528 bytes and is very simple.
Code:
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  char dataString[50] = {0};
  sprintf(dataString, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
  Serial.println(dataString);
}
void loop() {
}
If memory is a problem you can do something like this which takes 2220 bytes but is not a general solution.
Code:
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  Serial.begin(9600);
  for (uint8_t i = 0; i < 6; i++) {
    if (i) Serial.write(':');
    if (mac[i] < 16) Serial.write('0');
    Serial.print(mac[i], HEX);
  }
  Serial.println();
}
void loop() {
}
883  Using Arduino / Storage / Re: Windows Errors on opening SD card file on: July 16, 2012, 03:08:01 pm
Wow!  Looks like you are hitting every pothole.  The SYLK trap is a good one.
884  Using Arduino / Storage / Re: Windows Errors on opening SD card file on: July 16, 2012, 01:20:28 pm
If you remove the SD without closing the file you will most likely have a corrupt file.  Closing the file updates the directory entry for the file and insures the SD file structures are consistent.

If you check the SD for errors with the windows, the volume will probably have problems.

In Windows right click on the SD and select properties then click on the tools tab then click "Check now..."  under Error-checking.

If closing the file before removing the SD doesn't fix the problem post the exact Windows message and describe the app that was used to open the file
885  Using Arduino / Storage / Re: Logging 100 ksps with the Arduino internal ADC on: July 16, 2012, 12:46:35 pm
I did some tests but mostly looked at other people's work.

This is a good article on the AVR ADC and agrees with other tests http://www.openmusiclabs.com/learning/digital/atmega-adc/.

Here are the results of the SNR tests expressed as ENOB.

Where
Quote
ENOB = (SNR – 1.76dB)/6.02dB

At 100 ksps I must clock the ADC at 2 MHz so the above test says I get an ENOB of a little under 7.5.  Not too bad since I am recording 8-bit data.

At rates lower than about 70 ksps I can use 1 MHz for the ADC clock for better SNR/ENOB.

The ATmega datasheet makes it sound like an ADC clock above 200 kHz will kill accuracy but all test I find give results like the above for the 328p.

Pages: 1 ... 57 58 [59] 60 61 ... 99