Show Posts
Pages: 1 ... 11 12 [13] 14
181  Forum 2005-2010 (read only) / Exhibition / Re: sd card on: June 22, 2010, 01:40:08 am
Sorry for the delay.  I usually check my mail every day.

The pins are defined in the .h file.

In that file change:
#define setupDDRB DDRB |= 0x2c;  //set SS as output for cs
#define selectSDCARD PORTB &= ~0x04;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTB |= 0x04;  //set the SS to 1 to deselect the sd card

To:

#define setupDDRB DDRB |= 0x28;  //set SS as output for cs
#define setupDDRD DDRD |= 0x20;  //set SS as output for cs
#define selectSDCARD PORTD &= ~0x20;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTD |= 0x20;  //set the SS to 1 to deselect the sd card

In the .ccp file add:

setupDDRD;

after setupDDRB; in the function
unsigned char SDCARDclass::SD_reset(void)

While you are in the .h file delete all the ; at the end of the define macro statements. Its not correct to have them see:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268083394

Let me know if this works for you.
182  Forum 2005-2010 (read only) / Exhibition / Re: sd card on: December 06, 2009, 02:10:35 am
I added another example to my sd card class.
This is a program to check every byte on the sd card.

Code:
/* Connect sd card as shown in circuit diagram.
   Copy SDCARD folder into arduino-0017/hardware/libraries.
   This code will write/read directly to a sector on the sd card
     sector number 0 to about 1980000 for a 1.0GB card.
   This program writes 199 to every byte on the sd card.
   It will only stop when it gets read/write or memory error.
   We hope that is after the very last byte of the sd card.
*/

#include <SDCARD.h>
volatile unsigned char buffer[512] ;  // this 512 bytes read from or written to sd card
unsigned long sector = 0;  // the sector we will write or read from
int error = 0;  //the error will be 0 if the sd card works
unsigned long errormillis = 0;        // the time when error occured

void setup()                    // run once, when the sketch starts
{
 Serial.begin(9600);                     // initialize serial communication with computer
}

void loop()                     // run over and over again
{
  for (sector=0; sector<4000000 ; sector++)
  {
      int i = 0;  //general purpose counter
        for(i=0;i<512;i++)
      buffer[i]=199;      //fill the buffer with a number between 0 and 255
      
       error = SDCARD.writeblock(sector);  //write the buffer to this sector on the sd card

       if (error != 0)
         errormillis = millis();   //remember the time had error
       while (error !=0)  //we stay in this loop
     {
         Serial.print("sd card write error... code =  ");
         Serial.println(error);
         Serial.print("write error at sector=  ");
         Serial.println(sector);
         sendtime();
         delay(1000);   //send every second      
     }//end of if we have an error
    
        i = 0;  //general purpose counter
        for(i=0;i<512;i++)
      buffer[i]=0;      //clear the buffer
      
      error = SDCARD.readblock(sector);  //read into the buffer this sector in sd card

         if (error != 0)
         errormillis = millis();   //remember the time had error
         while (error !=0)   //we stay in this loop
     {
         Serial.print("sd card read error... code =  ");
         Serial.println(error);
         Serial.print("read error at sector=  ");
         Serial.println(sector);
         sendtime();
         delay(1000);   //send every second      
     }//end of if we have an error
    
      
       for(i=0; i<512; i++) //read 512 bytes
     {
      if (buffer[i] != 199)
      errormillis = millis();   //remember the time had error
      while (buffer[i] != 199)  //we stay in this loop
      {
         Serial.print("memory error at byte =  ");
         Serial.println(i);
         Serial.print("memory error at sector=  ");
         Serial.println(sector);
         sendtime();
         delay(1000);   //send every second      
      }//end of we have a memory error
     }//end of read 512 bytes
    
     if (sector % 100 ==0)
     {
       errormillis = millis();   //remember the time
       Serial.print("we have no errors up to sector =  ");
       Serial.println(sector);
       sendtime();
     }//end of ever 10 sectors
  }//end of 4000000 sectors done
}//end of loop
 
void sendtime()
{
         Serial.print("elapsed time hours= ");
         Serial.print(errormillis/3600000);
         Serial.print("  elapsed time minutes= ");
         Serial.print((errormillis/60000) % 60);
         Serial.print("  elapsed time seconds= ");
         Serial.println((errormillis/1000) % 60);
}//end of send the time

My 1.0GB sd card had its first error at sector 1984000.
That is after 1,015,808,000 bytes which must be the highest
number of bytes available on the card.

Each read or write takes 44 msec on the Arduino 2009.
The full program run took 49 hours and 24 minutes.
This is 89 msec for each write, read and check.

If anyone has tried my sd card class, some feedback would be appreciated.
 smiley
183  Forum 2005-2010 (read only) / Exhibition / Re: sd card on: December 03, 2009, 01:38:10 am
The read and write functions together use 1010 bytes of program memory.

This is a very small size because the sdcard library is written using the KISS principle.

However it does lead to limitations:
Cant use MMC cards.
Cant use old(ver.1 cards)- about before 2006.
Cant use HC sd cards(>2 GB)

Also you can see that it uses 512 bytes of RAM.

For the arduino 2009 this alocation of flash(32k) and ram(2k) is not a problem for my application
184  Forum 2005-2010 (read only) / Exhibition / sd card on: December 02, 2009, 04:35:44 pm
This class was written for the Arduino library.
It reads and writes directly to sectors on a sd card.

It has only two functions:

SDCARD.readblock(sector number); //read 512 bytes from this sector
SDCARD.writeblock(sector number); //write 512 bytes to this sector

The 512 bytes are read/write from a buffer which must be declared:

volatile unsigned char buffer[512] ;  //contains the 512 bytes to read/write

This class was written for my Arduino 2009 weather station.
I want to log up to 10 sensors for an extended period when the Arduino is not
connected to the computer.
To save a sample every  second over 12 months requires:

total bytes = 2 x 10 x 60 x 60 x 24 x 365 = 640 Mb

I use a 1.0Gb card.

The functions can both return a error value:

error = SDCARD.writeblock(sector);
error = SDCARD.readblock(sector);

If the card read/write does not work due to card failure or removal
the error will be greater than 0.
In my application this would mean the program can no longer operate.
In this case I send an error message instead of the normal samples
from the weater station.

This class does not use a FAT. Data is read/write to a sector direct.

The sd card circuit, the library and other files are at the site given below.
Download sdcardlibrary.zip

http://sourceforge.net/projects/arduinoweather/files/

If you have a 3.3v arduino the level change circuits will not be needed.

An example program to read/write to one sector is:

Code:
/* Connect sd card as shown in circuit diagram.
   Copy SDCARD folder into arduino-0017/hardware/libraries.
   This code will write/read directly to a sector on the sd card
     sector number 0 to 1980000 for a 1.0GB card.
*/

#include <SDCARD.h>
volatile unsigned char buffer[512] ;  // this 512 bytes read from or written to sd card
unsigned long sector = 99999;  // the sector we will write or read from
int error = 0;  //the error will be 0 if the sd card works

void setup()                    // run once, when the sketch starts
{
 Serial.begin(9600);                     // initialize serial communication with computer
}

void loop()                     // run over and over again
{
   if (Serial.available() > 0)   // do nothing if have not received a byte by serial
   {
    int inByte = Serial.read();
    if (inByte == 'r')  // send a "r" to start the read / write sector process
    {
      int i = 0;  //general purpose counter
        for(i=0;i<512;i++)
      buffer[i]=199;      //fill the buffer with a number between 0 and 255
      
       error = SDCARD.writeblock(sector);  //write the buffer to this sector on the sd card
      
       if (error !=0)
     {
         Serial.print("sd card write error... code =  ");
         Serial.println(error);      
     }//end of if we have an error
      
      error = SDCARD.readblock(sector);  //read into the buffer this sector in sd card

         if (error !=0)
     {
         Serial.print("sd card read error... code =  ");
         Serial.println(error);      
     }//end of if we have an error
      else
     {
       int number =0;
       for(i=0; i<512; i++) //read 512 bytes
     {
       number = buffer[i];    //convert to integer      
       if(((i % 8) == 0) & ( i != 0))  
       Serial.println("");   //write 8 then start a new line
       Serial.print(number);
       Serial.print("  ");   //tab to next number
     }//end of read 512 bytes
     }//end of else we have no error
    } //end of received "r"
   }//end of serial available
}//end of loop
185  Forum 2005-2010 (read only) / Exhibition / Re: air pressure sensor on: April 24, 2010, 02:05:21 am
The HP03D seems to be the only one in stock.

They all look to give accurate air pressure measurement.

If they were easily available here in Aussie I would try one!
186  Forum 2005-2010 (read only) / Exhibition / Re: air pressure sensor on: February 01, 2010, 12:43:14 am
Thanks for the replies.

Quote
april

I have the MPX4115AP, it can use a plastic pipe for a remote connection to a sealed tank.
I cannot say if its what you need.
I would be carefull of anything besides air.
Quote from data sheet:

pressure sensor operating characteristics and internal reliability and qualification tests are based on use of dry air as the pressure media. Media other than dry air may have adverse effects on sensor
performance and long term reliability.

187  Forum 2005-2010 (read only) / Exhibition / air pressure sensor on: January 29, 2010, 10:44:24 pm
I am making a weather station using Arduino 2009

For my pressure sensor I chose a MPX4115.
It was the cheapest (AUD $17) accurate one I could find.

The data sheet is at:

http://www.datasheetcatalog.org/datasheet/motorola/MPX4115.pdf

The air pressure range I wanted was 950 to 1070mb.
This equates to 95 to 107 kPa. Using Fig.4 from data sheet the output voltage will be 3.88 to 4.42v(nominal).

I use a LM3900 dc amplifier to amplify and shift the output voltage to 0 - 5.0v.
This uses the full range of the adc for the best accuracy available.

Code:
/*  A simple air pressure sensor check program
    The circuit uses one point calibration.
    Adjust the pot to give the known atmospheric pressure.
   1070 mb = 107 kpa = 802 mm Hg
 */

const int analogpin = 0;  // Analog input pin

void setup()
{
  Serial.begin(9600);   // initialize serial communications at 9600 bps:
}

void loop()
{
  int adcvalue = analogRead(analogpin);    // read the analog in value:            
  Serial.print("sensor = " );                        
  Serial.print(adcvalue);    // print the adc value to the serial monitor:
  long pressure = 950 + adcvalue / 8.5;  //convert it to milli bars
  Serial.print("\t pressure = ");      
  Serial.print(pressure);   // print the pressure
  Serial.println(" mb");
  delay(1000);   // wait 1 second before next sample                    
}

I calibrated the sensor using my Oregon scientific WMR 100.
This is the best I'm able to arrange. It is accurate enough for my use.

I have logged the data from the WMR 100 and my pressure sensor over some days and the result are within 2 mb over this time.

The sensor circuit and other files are at the site given below.
Download MPX4115.zip

http://sourceforge.net/projects/arduinoweather/files/
188  Forum 2005-2010 (read only) / Exhibition / light intensity sensor on: March 26, 2010, 08:01:43 pm
I wanted a light intensity sensor for my stevenson's screen.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268871131

I used a PerkinElmer Photoconductive Cell type VT9ØN3.

http://www.datasheetcatalog.org/datasheet/perkinelmer/VT500.pd

The arduino program:


Quote
/*   Simple program to demonstrate the light sensor
     The circuit and the constants are described in
     the pdf file.
*/

unsigned int rec_data = 0;  //the integer received
const double RK = .00139; //circuit and device constant
const double gamma = 0.85; // the device power constant
const double V = 8.0;  //the circuit supply voltage
const int analogpin = 0;  // Analog input pin

void setup()   // run once, when the sketch starts
{
 Serial.begin(9600);      // initialize serial communication with computer
}

void loop()                     // run over and over again

 rec_data = analogRead(analogpin);    // read the analog in value;
 Serial.print("adc value = " );                        
 Serial.print(rec_data);    // print the adc value to the serial monitor:
 Serial.print("\t light intensity = ");
 double vo = (rec_data * 5.0) / 1024.0; //the voltage at the adc
 vo = pow(RK * (V/vo -1) , -1.0/gamma);  //the light intensity
 Serial.print(vo,DEC);   // print the light intensity
 Serial.println(" lux");
 delay(5000);
}//end of loop


Using my indoor weather program we log 24 hours:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265087241




The variations are due to clouds moving through the sensor's field of vision.


The circuit and calibration details are available from:
Download LIGHT.pdf


http://sourceforge.net/projects/arduinoweather/files/
189  Forum 2005-2010 (read only) / Exhibition / Re: stevensons shield on: March 18, 2010, 05:16:53 pm
westfw

Yes it's foam, pure PS foam with no protective coating.

Here in Aussi we use millions of them. They are used once and
mostly recycled.
The size I'm using is a standard broccoli box.
We can purchase them for a $1 at the supermarket to carry home our vegetables with a little ice.
They degrade in the sun but are usefull for about a year.




Ran Talbott

Thats a good looking site.  I like that shield and it sure does
look like a bird box.
I have noticed birds resting on mine as it has a nice flat surface for them.
190  Forum 2005-2010 (read only) / Exhibition / stevensons shield on: March 17, 2010, 07:12:11 pm
I have completed my indoor weather station:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265087241

The next step is to include sensors from a remote outdoor location.
All my sensors use an unsigned integer format. I have written the code
to send the sensor data from a remote location:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268083394

A common way to house the sensors is in a Stevenson Screen:

http://en.wikipedia.org/wiki/Stevenson_screen

The traditional Stevenson Screen is a box shape, constructed of wood, in a double-louvered design.
This is very costly and needs to be maintained-also costly.
There are many examples of home built screens:

http://www.loganvillageweather.com/station/stevenson.html

I have used a polystyrene produce box as my shield.
The sensors are mounted in a wooden box covered by the poly box.

A Stevenson screen or instrument shelter is an enclosure to shield meteorological instruments against precipitation and direct heat radiation from outside sources, while still allowing air to circulate freely around them.

The poly box shields the sensors but to circulate air I have used a 12v fan. I have battery backed 12v available and this is not a problem.
The cost problem is solved by the poly box being disposable and very cheap




The bottom of the box is 1.3m above the ground.
The support is a galvanized pipe concreted into the ground.
Concrete is a good conductor and this pipe makes a good earth point.

More design information is available from:
Download Stevenson.pdf


http://sourceforge.net/projects/arduinoweather/files/  
191  Forum 2005-2010 (read only) / Exhibition / Re: software serial on: March 12, 2010, 10:50:36 pm
Very good.

I use C++ for programmers by P.J.Dettel (2009).

He does use all the above ,as you say, except cant we name variables
in lower case ?
192  Forum 2005-2010 (read only) / Exhibition / Re: software serial on: March 11, 2010, 12:10:13 am
April

Thanks for your reply.

You certainly do not need this as well as softwareserial for general serial work.

Serial software is not a hard task and I did write it at first for my own learning experience. When it started getting timing problems at high speeds I checked softwareserial.

If you send an unsigned integer it gets sent through:

Quote
void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
{
  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  unsigned long i = 0;

  if (n == 0) {
    print('0');
    return;
  } 

  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--)
    print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}


You then have to do the reverse to get at your integer.

You can split up the integer at the start and use two:

Quote
void SoftwareSerial::print(char c)
{
  print((uint8_t) c);
}


Then combine the two to get the integer.

My application must have a timeout. I could have modified softwareserial I suppose.

As I aready had a working send integer that I liked I incorporated mine in my weather program.
I put it on forum because some are following the weather program and I wont to keep it complete.

Groove

Thanks for your reply.

My ANSI C programming text does not specify upper case for the C preprocessor.
In fact it uses lower case in its examples (p88 Kernighan & Ritchie).
My C++ text does not specify either but it does use capitals in its examples(p900 Deitel).

I have been absent from the scene for some time so I will accept your
statement that it is "usual" to use capitals.

You are dead right about the   ;  
That slipped through as the compiler can cope with   ;;

I will watch that in future.
193  Forum 2005-2010 (read only) / Exhibition / software serial on: March 08, 2010, 04:23:14 pm
This is a serial data transmission class for my weather station.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265087241

It has 3 functions:

SSERIAL.begin(int baud)
This sets the baud rate. The int baud sets the pulse width in microsecs.
If this function is not used a default pulse width of 2500 microsecs will
be set to give a baud rate 0f 400.

unsigned int SSERIAL.request()
This requests a remote audino to send in serial a unsigned integer.
If the remote does not respond in 1 second the function returns 65535.

void senddata(unsigned int send_data)
This waits for a request then sends in serial the unsigned integer .
There is no timeout.

I have a remote site to monitor weather data. This data is collected using an arduino pro.




My "master" station is indoors and uses a arduino 2009.
This arduino will request data from the remote arduino.

On receiving a request the remote will send an unsigned integer in serial.
All of my weather sensors produce unsigned integers.
The class uses software serial. It operates in the same manner as
SoftwareSerial library in the arduino-0017.

I have included a timeout which is used to produce an error message
at the master.

The remote send the serial data from its D3.
It listens on D2 for the request (LOW).

The master sends the request (LOW) from D3.
It listens for serial data on D2.

The following details apply to windows:

To try out this class you will need to store the SSERIAL folder in:

C:\arduino-0017\hardware\libraries

Or where you have your arduino-0017.

Start arduino-0017 and look under file-examples.

Select master for your main arduino.
Upload it to the port it is allocated - mine was COM8.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the master arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.request() send request to remote arduino.
      Then it waits for an unsigned integer to be sent back in serial.
      Returns 65535 if times out after 1 second.
      The request is sent (LOW) on D3.
      The data is received on D2.
*/

#include <SSERIAL.h>

int baud = 100;   //the pulse width of the serial data
unsigned int rec_data = 0;  //the integer received
void setup()   // run once, when the sketch starts
{
 Serial.begin(9600);      // initialize serial communication with computer
 SSERIAL.begin(baud);   // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
 rec_data = SSERIAL.request();
 Serial.println(rec_data);  //print the data from remote
 delay(100);
}//end of loop


Start another instance of arduino-0017 and look under file-examples.

Select slave for your slave arduino.
Upload it to the port it is allocated - mine was COM9.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the slave arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.senddata(send_data); Waits until request for data no timeout.
      when it gets request it sends send_data in serial to master.
      D2 is polled for request (LOW).
      Data is sent on D3.
*/

#include <SSERIAL.h>

unsigned int send_data = 30555;  //the integer to send
const int baud = 100;   //the pulse width of the serial data

void setup()            // run once, when the sketch starts
{
 SSERIAL.begin(baud);    // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
  SSERIAL.senddata(send_data);   //sends data when requested
}//end of loop


There is also another example you can use for the master.
master_error
This will check groups of 100 data transfers and print out the number
of errors.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the master arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.request() send request to remote arduino.
      Then it waits for an unsigned integer to be sent back in serial.
      Returns 65535 if times out after 1 second.
      The request is sent (LOW) on D3.
      The data is received on D2.
*/

#include <SSERIAL.h>

int baud = 100;   //the pulse width of the serial data
//anything faster than this gives large error rate
unsigned int rec_data = 0;  //the integer received
void setup()   // run once, when the sketch starts
{
 Serial.begin(9600);      // initialize serial communication with computer
 SSERIAL.begin(baud);   // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
 unsigned int temp = 0;
 unsigned int errors = 0; //number of errors
 byte j = 0;   // for start counter
 for (j = 0; j < 100 ; j +=1)   //get 100 data transfers
 {
 temp = SSERIAL.request();  //get an integer transfer
 if (temp != 30555)
 {
 //Serial.println(temp);  
 errors +=1;  //we have an error
 }//end of != 30555
 delay(1);
 }//end of get 100 data transfers
 Serial.println(errors);
 delay(1);
}//end of loop


With a pulse width of 100 microsecs there should never be any errors.
If you decrease the pule width(increase baud rate) you will find that
errors start to occur.

Below 80 it drops its bundle. The same happens for SoftwareSerial
there is too much slop in the timing when using software.

The new programs and diagrams are available from:
Download SERIAL.zip


http://sourceforge.net/projects/arduinoweather/files/
194  Forum 2005-2010 (read only) / Exhibition / Re: Cascaded shift registers, 7-seg displays, PC input on: February 17, 2010, 08:07:40 pm
I have completed a 4 digit display for my weather station.


http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266454689/0#0
195  Forum 2005-2010 (read only) / Exhibition / Re: Cascaded shift registers, 7-seg displays, PC input on: February 01, 2010, 09:05:24 pm
Thanks paul.

There are many ways to skin a cat.

But for each 7 seg display you need a driver.
Then why not use the 74HC595 and also get the shift register.

If you use BCD to 7 segment drivers you are limiting yourself to
0 to F.
With your method we have full use of the 7-seg display.

It seems obvious to me!

As soon as I get my sensors of the protoboard I will be trying
out your idea.
Pages: 1 ... 11 12 [13] 14