Arduino+VDIP1+help=pendrive data logger :)

HI
I’ve started to build a pendrive/usb drive datalogger.

I’m using duemilanove, VDIP1 in serial mode(RTS&CTS tied together) and LM35 temperature sensor.

Using help found on the net I wrote a program that should read the LM35 and write the human readable value on the drive, in a file.txt.
I found information about arduino and vdip1 here:
arduino.cc/playground/Main/UsbMemory
unlogic.co.uk/2009/03/usb-storage-and-arduino/

#include <NewSoftSerial.h>

NewSoftSerial mySerial(3, 4); // set pins for serial port
int tempPin = 0; // set sensor pin
float tempC = 0; // declare temperature value
int stoppin = 7; // set stop button pin
int ledPin = 13; // set status led pin
void setup()
{
pinMode(stoppin, INPUT); // declare stoppin input
pinMode(ledPin, OUTPUT); // declare ledpin output

mySerial.begin(9600); // init serialport @ baud 9600
mySerial.print("IPA"); // tell vdip to accept ascii
mySerial.print(13, BYTE); // return character/vdip end of command
mySerial.print("OPW LOG.TXT"); // open/create logfile
mySerial.print(13, BYTE); // return character
}

void loop()
{
if (digitalRead(stoppin) == LOW) // check button
// if the button is not pushed
{
tempC = analogRead(tempPin); //read temp sensor
tempC = (5.0 * tempC * 100.0)/1024.0; //convert tempC to decimal
delay(100); // wait 100 milliseconds
mySerial.print("WRF "); //start writing to file
mySerial.print("4"); // declare number of characters to be written ??
mySerial.print(tempC); // write temp
delay(100);
mySerial.print(13, BYTE);
delay(800);
}
else // if button is pressed when checked
{
delay(100); // wait 0.1 seconds
mySerial.print("CLF LOG.TXT"); // close file
mySerial.print(13, BYTE);
delay(100);
// blink onboard led on pin 13 three times, so I know when I can poweroff
digitalWrite(ledPin, HIGH);
delay(250);
digitalWrite(ledPin, LOW);
delay(250);
digitalWrite(ledPin, HIGH);
delay(250);
digitalWrite(ledPin, LOW);
delay(250);
digitalWrite(ledPin, HIGH);
delay(250);
digitalWrite(ledPin, LOW);
delay(250);
exit; // stop looping so vdip stops and the device can be disconnected
}// and the pendrive can be removed 
}

As far:

  • the logger should read the sensor and write the value about once every second, but the leds on the vdip and pendrive blink for a short time and remain lighted (one on vdip and the one on the pendrive)
  • I managed to write only an empty file (once).
  • exit; doesn’t seem to stop execution of program because the led keeps blinking if I keep the stop button pressed.

Thankyou in advance.

The exit; command is ignored by the avr-gcc compiler, apparently.

If you want to stop your program from doing any more processing, use while (1); instead of exit;

Or put the processor to power-down sleep. The downside to this method is that an interrupt will wake it up.

  • Brian

The program execution seems to stop with while(1). But the logger doesn't work, when I connect the USB for power, the led on pin 13 blinks, so I think it doesn't read the stop button, and it doesn't seem to create the file on the pendrive. (leds on vdip1 and pendrive blink and stop when led on pin 13 blinks, the pendrive led remains lighted). I've tried replacing

if (digitalRead(stoppin) == LOW)

with

if (digitalRead(stoppin) == 0)

and I've added

stoppin = 0;
delay(500);

with no effect.

le: I'm afraid my code is bad for the vdip1. I searched some more and I found i have to tell the exact number of characters to be written because if I send less characters I the vdip hangs (I guess that's why the leds on vdip and pendrive remain lighted). So I need to convert tempC from float to int, but I don't know how.

I poked around with the code, and using while(1); the program execution stops, but the vdip1 doesn't write on the pendrive. I've swiched to the default Serial library, using Serial.print to see the arduino output, and everything seems ok (IPA OPW LOG.TXT WRF 225CLF), but just afer poweron, the vdip hangs (one LED lighted on VDIP, pendrive led lighted). I added delay(5000); just before the vdip initialisation, but the vdip deos the same.

LE: I found and corrected the errors. I'll post the code later. Here are the corrections: - added 6 seconds delay from arduino poweron to vdip initialisation - added missing mySerial.print(13, BYTE); after declaration of number of characters to be written - added some delays to compensate for not using handshaking/rts+cts - added cosmetic/optional messages to be written on the pendrive. - added pendrive suspend after pressing stop logging button

Thanks for posting your solution. It always helps the person who has the same setup and finds this thread through a search next month!

As I’ve said, I’ll post the final code for the data logger.
With the code the temperature from an temperature sensor can be logged on a pendrive.

#include <NewSoftSerial.h>

NewSoftSerial mySerial(3, 4); // definire pini port serial
int tempPin = 0; // setare pin senzor
int voltPin = 1; // setare pin senzor
float voltV = 0; // valoare initiala a tens
float tempC = 0; // valoare initiala a temp
int stoppin = 2; // setare pin buton stop
int ledPin = 13; // stare pin led stare
void setup()
{
  pinMode(stoppin, INPUT); // declarare stoppin ca intrare
  pinMode(ledPin, OUTPUT); // declarare ledPin ca iesire
  digitalWrite(ledPin, HIGH); // aprinde ledul
  delay(6000);
  digitalWrite(ledPin, LOW); // stinge ledul
  mySerial.begin(9600); // initializeaza port serial baud 9600
  mySerial.print("IPA"); // seteaza vdip sa accepte comenzi ascii
  mySerial.print(13, BYTE); // caracter return
  delay(1000);
  mySerial.print("OPW "); // deschide sau creeaza fisierul de log
  mySerial.print("LOG");
  mySerial.print(".RTF");
  mySerial.print(13, BYTE); // caracter return
}

void loop()
{
  if (digitalRead(stoppin) == LOW) // verifica butonul
  {
    tempC = analogRead(tempPin); //citire temperatura
    delay(300);
    tempC = (5.0 * tempC * 100.0)/1024.0; //convertire citire in zecimal
    digitalWrite(ledPin, HIGH); // aprinde ledul
    delay(100); // asteapta 250 milisecunde
    digitalWrite(ledPin, LOW); // stinge ledul
    mySerial.print("WRF "); //incepe scrierea in disc
    mySerial.print("6"); //declara numarul caracterelor ce vor fi scrise
    mySerial.print(13, BYTE); // scrie termperatura
    mySerial.print(tempC);
    delay(100); // asteapta 100 milisecunde
    mySerial.print(32, BYTE);
    voltV = analogRead(voltPin); //citire tensiune
    delay(300);
    voltV = voltV/102.0;
    delay(100);
    mySerial.print("WRF ");
    mySerial.print("5");
    mySerial.print(13, BYTE);
    mySerial.print(voltV);
    delay(100);
    mySerial.print(13, BYTE);
    mySerial.print(13, BYTE);
  }
  else // daca butonul este apasat
  {
    delay(1000); // asteapta 100 milisecunde
    mySerial.print("CLF LOG");
    mySerial.print(".TXT");
    delay(100);
    mySerial.print(13, BYTE);
    digitalWrite(ledPin, HIGH); // aprinde ledul
    delay(250); // asteapta 250 milisecunde
    digitalWrite(ledPin, LOW); // stinge ledul
    delay(250); // asteapta 250 milisecunde
    digitalWrite(ledPin, HIGH); // aprinde ledul
    delay(250); // asteapta 250 milisecunde
    digitalWrite(ledPin, LOW); // stinge ledul
    delay(250); // asteapta 250 milisecunde
    mySerial.print("SUD");
    mySerial.print(13, BYTE);
    digitalWrite(ledPin, HIGH); // aprinde ledul
    delay(250); // asteapta 250 milisecunde
    digitalWrite(ledPin, LOW); // stinge ledul
    delay(250); // asteapta 250 milisecunde
    while(1); // opreste logarea
  }
}

Enjoy.

ps: ignore the comments if you don’t know Romanian :slight_smile:

hmm. are you sure that's the final code? It has a bug or two and doesn't work when I try to fix them.

for example, you open a .RTF file but close a .TXT

I'm not sure if this is wrong, but at one point you write a (32, BYTE) as opposed to a (13, BYTE). I think there's a double (13, BYTE) as well somewhere, but again I don't know if that's wrong.

When I make it a .TXT, it makes a file but it's blank. any ideas?