Show Posts
Pages: 1 ... 68 69 [70] 71 72 ... 110
1036  Using Arduino / Storage / Re: Data Logger SD, String stops earlier than expected on: July 23, 2012, 06:19:13 pm
Gasp!  The problem appears to be in free(),115552.msg869983.html#msg869983.
1037  Development / Suggestions for the Arduino Project / Re: String corrupts the heap and crashes on: July 23, 2012, 06:16:39 pm
Now you see why malloc/heap is not used in serious embedded projects.  This sort of thing happens over and over.

I agree with Graynomad, one could consider allocation of memory at start-up as in the JSF standard.

I never use dynamic memory in my libraries or applications but waste lots of time chasing bugs that are reported in my software that turnout to be due to dynamic memory.

In the future I simply won't look for bugs if an application uses dynamic memory.  Well, maybe I will look for obvious stuff.

This was good for a laugh, failure of free, wow. 

I have more respect for the decision of the real embedded system pros when they forbid use of dynamic memory in standards for critical systems.
1038  Development / Suggestions for the Arduino Project / Re: String corrupts the heap and crashes on: July 23, 2012, 03:44:35 pm
In my opinion shot-in-dark things like allocate 10 or 20 extra bytes are the wrong way to fix bugs like this.

You then stand the chance of making it sill happen but less often.

There are lots of cases where this type of fix was used in safety critical systems with horrible outcome.  Then you trust the system because it seems to work but the bug is still there.

Paul usually tries to get the Arduino group to accept his fixes.  I hope the Arduino group would apply a fix if Paul submitted it.

1039  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 and motor vehicle coding standards like MISRA have statements like this:
MISRA C++ rule 18-4-1, dynamic heap memory allocation cannot be used.
1040  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.
#include <MemoryFree.h>
void setup() {
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());
The output looks like this and the value of freeMemory() in the last column indicates a corrupt heap.
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,115451.0.html
1041  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:
#include <MemoryFree.h>
void setup() {

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());

    //Increment ID number

Here is the printout.  The last column is the value returned by freeMemory() which is nonsense.
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
//    free_memory += freeListSize();
I get this
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.
1042  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,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 The files for DigitalPin and SoftSPI are in the utility folder of SdFat.  I will soon post these files as a standalone library.
1043  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

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.
1044  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:
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.

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

    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:
#include <SdFat.h>
SdFat sd;

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

1045  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:
 uint32_t bytesLeft;
  bytesLeft = file.fileSize() - file.curPosition();

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

1046  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.
1047  Using Arduino / Storage / SdFat update on: July 19, 2012, 04:23:35 pm
A new version of SdFat,, is available here

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:
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

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.
1048  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. 
1049  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.

1050  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.
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  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);
void loop() {
This sketch takes 3528 bytes and is very simple.
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  char dataString[50] = {0};
  sprintf(dataString, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
void loop() {
If memory is a problem you can do something like this which takes 2220 bytes but is not a general solution.
uint8_t mac[] = {110, 5, 30, 0, 50, 12};
void setup() {
  for (uint8_t i = 0; i < 6; i++) {
    if (i) Serial.write(':');
    if (mac[i] < 16) Serial.write('0');
    Serial.print(mac[i], HEX);
void loop() {
Pages: 1 ... 68 69 [70] 71 72 ... 110