Using both ethernet and sd on Freetronics EtherMega

Combining the power of the ATmega2560 MCU with onboard Ethernet, a microSD card slot, an efficient switchmode power supply, and a small prototyping area. [Product page]

Using both ethernet and sd on Freetronics EtherMega

Postby rubberbrick » Thu May 31, 2012 5:08 am

I seem to be having some problems getting my basic webserver sketch working. I have included it into a datalogging and differential control system for solar hot water which works well on its own (Thanks to all the coders from whom I have plagiarised much of the script).
When the webserver script is included the relay pin 7 stops going high and I am unable to access the mega via ip address (mega connected to wireless router).
Not sure if it may be an issue with lines
// Initialize sd card
pinMode(53, OUTPUT); // set the SS pin as an output (necessary!) pin 53 on mega
digitalWrite(53, HIGH); // but turn off the W5100 chip!


When I plug mega into router there appears to be a lot of activity and the router indicates that it has a wired connection.
Below is full code, hopefully someone will be able to make sense of it, sorry a bit long winded


//Libraries needed for Dallas 1-wire thermometers
#include <OneWire.h>
#include <DallasTemperature.h>
//Library needed for the Chronodot RCT
#include <Wire.h>
#include "Chronodot.h"
//Libraries needed for sd card operation
#include <SD.h>
//define input pin 2 for 1-wire bus


#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 177);
// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);


#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 10 //Sensor resolution at 0.25°C
// Setup a oneWire instance to communicate with OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
// sd file name
File myFile;
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

int switchPin = 31; // switch is connected to pin 31
int val; // variable for reading the pin status
// RTC stuff
Chronodot RTC; 

//define pin 7 for pump relay
const int pump = 7;

//These variables are where the adjustments are made that effect when system will cycle.

//set maximum tank temperature
int tankMax = 75;

//if tankMax is met, system won't cycle back on till tank cools down a bit. Keeps from overcycling.
float tankCooldown = 1;

//set how much hotter collector should be than tank before turning on pump
int diff = 5;

//Pump shuts off when temp rise is below this value
float minRise = 1;


//SET YOUR THERMOMETER ADDRESSES!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

byte collectorThermometer[8] = {0x28, 0x67, 0xBD, 0x96, 0x03, 0x00, 0x00, 0xF7}; //ic5
byte loopReturnThermometer[8] = {0x28, 0xD6, 0xDB, 0x96, 0x03, 0x00, 0x00, 0x4A}; //ic1
byte tankbottomThermometer[8] = {0x28, 0xDD, 0xAC, 0x96, 0x03, 0x00, 0x00, 0x8E}; //ic3
byte tanktopThermometer[8] = {0x28, 0xDF, 0xE2, 0x96, 0x03, 0x00, 0x00, 0xAB}; //ic7
byte loopReturnUsedThermometer[8] = {0x28, 0xE5, 0xE2, 0x96, 0x03, 0x00, 0x00, 0x89}; //ic2
byte coldinThermometer[8] = {0x28, 0x2F, 0xBE, 0x96, 0x03, 0x00, 0x00, 0x6D}; //ic6
byte coldoutThermometer[8] = {0x28, 0x81, 0xA6, 0x96, 0x03, 0x00, 0x00, 0x60}; //ic4

//declare some variables

//used for control logic
static bool pumpOn;
static bool tankMaxed;

//temperature variables
float rise;
float tank;
float collector;
float tankbottom;
float loopReturn;
float loopUsed;
float coldIn;
float coldOut;
//float outside; 
float differential;
char filename[] = "000000.txt";
char buffer[18];
void setup ()
{
//start serial port and print information for debugging
  Serial.begin(9600);
  pinMode(switchPin, INPUT); // Set the switch pin as input
  // start the ethernet connection
 // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();

// Initialize Chronodot
  Wire.begin();
    RTC.begin();
   // if (! RTC.isrunning()) {
   // Serial.println("RTC is NOT running!");
   
 // Initialize sd card
 pinMode(53, OUTPUT); // set the SS pin as an output (necessary!) pin 53 on mega
 digitalWrite(53, HIGH); // but turn off the W5100 chip!

 Serial.print("Initializing SD card...");
 if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  // Start up the sensors library
  sensors.begin();

   // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.println ("");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");
  Serial.println ("");

    //set pins to output
  pinMode (pump, OUTPUT);
  
  // set the sensor resolution to TEMPERATURE_PRECISION
  sensors.setResolution(collectorThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(loopReturnThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(tankbottomThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(tanktopThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(loopReturnUsedThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(coldinThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(coldoutThermometer, TEMPERATURE_PRECISION);
     
  //delay a bit to give everything time to start
  delay (1000);
}

void WriteDateTime(byte p) // function to write date and time to data file
{
   DateTime now = RTC.now();
   myFile = SD.open(filename, FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
     // myFile.println(tempC);
      //Write date
      if(now.day() < 10) myFile.print("0");
    myFile.print(now.day(), DEC);
    myFile.print('/');
    if(now.month() < 10) myFile.print("0");
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.year(), DEC);
    myFile.print(',');
    //Write time
    if(now.hour() < 10) myFile.print("0");
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    if(now.minute() < 10) myFile.print("0");
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    if(now.second() < 10) myFile.print("0");
    myFile.print(now.second(), DEC);
    myFile.print(',');
    if (p == 1)
    {
    myFile.print(now.tempC(), 1);
    myFile.print(',');
    }
      // close the file:
    myFile.close();
   
  } else {
    // if the file didn't open, print an error:
    Serial.println("error WriteDateTime");
  }
  
}
//Function to write data to SD card
void WriteSD(DeviceAddress deviceAddress, int rr)
{
  float tempC = sensors.getTempC(deviceAddress);
  myFile = SD.open(filename, FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
      myFile.print(tempC);
      myFile.print(",");
      
      if (rr == 1) myFile.println("");
// close the file:
    myFile.close();
  // printTemperature(deviceAddress);
  } else {
    // if the file didn't open, print an error:
    Serial.println("error WriteSD");
  }
  
}
 
 //Serial output Date, Time and RTC temperature
 void PrintOut()
{
  DateTime now = RTC.now();
   Serial.print(now.year(), DEC);
    Serial.print('/');
    if(now.month() < 10) Serial.print("0");
    Serial.print(now.month(), DEC);
    Serial.print('/');
    if(now.day() < 10) Serial.print("0");
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    if(now.hour() < 10) Serial.print("0");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    if(now.minute() < 10) Serial.print("0");
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    if(now.second() < 10) Serial.print("0");
    Serial.print(now.second(), DEC);
    Serial.println();
    Serial.print("RTC ");
    Serial.print(now.tempC(), 1);
    Serial.print(" - ");
  }
   
   // function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress, String Sensor)
{
   float tempC = sensors.getTempC(deviceAddress);
    Serial.print(Sensor);
    Serial.print(" ");
   Serial.print(tempC);
   Serial.print(" - ");
  
   } 

//sensorValue function
//reads temp from sensors and returns as floating point value in C

float sensorValue (byte deviceAddress[])
{
  float tempC = sensors.getTempC (deviceAddress);
  float tempF = (DallasTemperature::toFahrenheit(tempC));
  return tempC;
}


//Write pump status to SD card on change of status
 void WriteSDPumpStatus(byte OnOff)
{
     WriteDateTime(0); //Write datetime stamp for pump status
     delay(500);
     
    myFile = SD.open(filename, FILE_WRITE);
  
  // if the file opened okay, write pump status to it:
  if (myFile) {
      if (OnOff == 1)
        {
          myFile.println("Pump On");
        }  
      else if (OnOff == 0)
      {
        myFile.println("Pump Off");
      } 
   // close the file:
    myFile.close();
  // printTemperature(deviceAddress);
  } else {
    // if the file didn't open, print an error:
    Serial.println("error WritePumpStatus");
  }
}

//Read Sd card file and dump to serial port
void ReadFile(char* Fname)
{
// open the file for reading:
 // myFile = SD.open("test2.txt");
 
 myFile = SD.open(Fname, FILE_READ);
  if (myFile) {
    Serial.println(Fname);
    
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
     Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
   // if the file didn't open, print an error:
  

    Serial.println("error readfile");
    return;
  }
}
//Function to check if file exists for this month if not create one 
void getFileName(){

DateTime now = RTC.now();

filename[0] = (now.year()/1000)%10 + '0'; //To get 1st digit from year()

filename[1] = (now.year()/100)%10 + '0'; //To get 2nd digit from year()

filename[2] = (now.year()/10)%10 + '0'; //To get 3rd digit from year()

filename[3] = now.year()%10 + '0'; //To get 4th digit from year()

filename[4] = now.month()/10 + '0'; //To get 1st digit from month()

filename[5] = now.month()%10 + '0'; //To get 2nd digit from month()

//Check file name exist?

if (SD.exists(filename)) {

}

else {

myFile = SD.open(filename, FILE_WRITE);
myFile.println("Date,Time,RTC,Collector,Return Loop,Tank Bottom,Tank Top,Return Loop Used,Cold In,Cold Out");
myFile.close();
}
}

void loop ()
{

  //get all sensor values
  sensors.requestTemperatures();
  //Call function to check if file exists if not create file name ie 1 file for each month
  getFileName();
  //Write Datetime stamp to sd card
  WriteDateTime(1);
  
  //Serial print time and rtc temp data
  PrintOut();
  
  //assign value to some variables
  
  collector = (sensorValue(collectorThermometer));
  loopReturn =(sensorValue(loopReturnThermometer));
  tankbottom = (sensorValue(tankbottomThermometer));
  tank = (sensorValue(tanktopThermometer));
  loopUsed = (sensorValue(loopReturnUsedThermometer));
  coldIn = (sensorValue(coldinThermometer));
  coldOut = (sensorValue(coldoutThermometer));
   
  // Write temperature data to SD card second parameter is to determine linefeed
  WriteSD(collectorThermometer,0);
  WriteSD(loopReturnThermometer,0);
  WriteSD(tankbottomThermometer,0);
  WriteSD(tanktopThermometer,0);
  WriteSD(loopReturnUsedThermometer,0);
  WriteSD(coldinThermometer,0);
  WriteSD(coldoutThermometer,1);
   
  //Print temperature data to serial monitor
  printTemperature(collectorThermometer,"Collector");
  printTemperature(loopReturnThermometer,"Return");
  printTemperature(tankbottomThermometer,"Tank Bottom");
  printTemperature(tanktopThermometer,"Tank Top");
  printTemperature(loopReturnUsedThermometer,"Loop Used");
  printTemperature(coldinThermometer,"Cold In");
  printTemperature(coldoutThermometer,"Cold Out");

  differential = collector - tankbottom;

  //if pump is running, set rise to difference between loopreturn and tankbottom else rise is set to 0
  if (pumpOn)
    {rise =  loopReturn - tankbottom;}
  else {rise = 0;}

    Serial.print ("differential ");
  Serial.println (differential);
  Serial.print ("rise ");
  Serial.println (rise);
  Serial.print ("pump state ");
  Serial.println (pumpOn);
  Serial.println ("");
  Serial.println ("");
  Serial.println ("");
  Serial.println ("");
  
  if (tankMaxed)
  {
    if (tank < (tankMax - tankCooldown ) )
   { 
      tankMaxed =false;
    }
  }
  else
  {
    if ( tank > tankMax )
    { 
     tankMaxed = true;
    digitalWrite (pump, LOW);
    pumpOn = false;
    WriteSDPumpStatus(pumpOn);
     }
  }

//if tankMaxed bool is false, cycle as solar heat is available
  if (!tankMaxed)
  {
    if (pumpOn)
    {
      if ( ( (rise < minRise) && (differential < (diff - 1) ) ) )
      {
        digitalWrite (pump, LOW);
        pumpOn =false;
        WriteSDPumpStatus(pumpOn);
      }
    }
    else
    {
      if (differential > diff )
     {
        digitalWrite (pump, HIGH);
       pumpOn = true;
      WriteSDPumpStatus(pumpOn); 
      }
    } 
  }     
 
   delay (10000);


val = digitalRead(switchPin); // read input value and store it in val
 if (val == HIGH) { // check if the button is pressed
//  digitalWrite(ledPin, HIGH);   // turn LED on
   ReadSerial();   // read serial input in format d201203 ie d for date then yyyymm
  }
 
 // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.print("Collector - ");
          client.print(collector);
          client.print("Return - ");
          client.print(loopReturn);
          client.print("Tank Bottom - ");
          client.print(tankbottom);
          client.print("Tank Top - ");
          client.print(tank);
          client.print("Loop Used - ");
          client.print(loopUsed);
          client.print("Cold In - ");
          client.print(coldIn);
          client.print("Cold Out - ");
          client.print(coldOut);
          client.println();
          break;
           }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
      
  



//SD card functions
void SDCardInfo(){
  const int chipSelect = 4;
    if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
       return;
  } else {
   Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }
  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
  
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
  Serial.println();
}
  
void ReadSerial() //uses serial monitor to display file info from sd card and asks for name of file to download

  SDCardInfo();
  Serial.println("Enter file to download in format 201203.TXT");
  Serial.flush();
 int SDRead = digitalRead(switchPin);
while (SDRead == HIGH){
  if (Serial.available() > 0) {
    int index=0;
    delay(100); // let the buffer fill up
    int numChar=Serial.available();
    if (numChar>11) {
      numChar=11;
    }
    while (numChar--) {
      buffer[index++] = Serial.read();
    }
    splitString(buffer);
    SDRead = LOW;
  }
}
}

//  digitalWrite(ledPin, HIGH);   // turn LED on
  
void splitString(char* data) {
  Serial.print("Data entered: ");
  Serial.println(data);
  char * parameter;
 parameter = data;
    // if ((data[0] == 'd') || (data[0] == 'D'))
    //{
      
      
   ReadFile(parameter);
  // Clear the text and serial buffers
  for (int x=0; x<12; x++) {
    buffer[x]='\0';
  }
  Serial.flush();

}


[/quote][/quote]
rubberbrick
 
Posts: 3
Joined: Thu May 31, 2012 4:30 am

Re: Using both ethernet and sd on Freetronics EtherMega

Postby rubberbrick » Sat Jun 02, 2012 2:31 am

:D Solved:

reply from SurferTim on Arduino Forum:

I think your setup should be like this:
Code:

// Initialize sd card
pinMode(53, OUTPUT); // set the SS pin as an output (necessary!) pin 53 on mega
pinMode(10,OUTPUT); // set the w5100 SS pin to OUTPUT
digitalWrite(10, HIGH); // and turn off the W5100 chip!


Digital pin 10 is the SS pin for the 5100, not 53. Freetronics data shows the pin assignment has been kept the same as the Mega with an ethernet shield.

add: I see they also used a switching type power regulator instead of the linear. Good for them!!


My reply

Brillant, after making those changes was still not working, I then checked my router ip settings (obviously not too clued up here) and found under DHCP server setting the IP Pool starting to ending address was 192.XX.2.2 to 192.XX.2.100 and I had assigned the ethermega an address outside of this.
So all up and running, next I would like the browers it to refresh automatically any ideas.
thanks for your help on previous issue.
rubberbrick
 
Posts: 3
Joined: Thu May 31, 2012 4:30 am

Re: Using both ethernet and sd on Freetronics EtherMega

Postby rubberbrick » Sun Jun 03, 2012 2:04 am

Ok to answer my own question about refresh found solution http://arduino.cc/en/Tutorial/WebServer
Code: Select all
client.println("<meta http-equiv=\"refresh\" content=\"5\">");


Image
Amazing
rubberbrick
 
Posts: 3
Joined: Thu May 31, 2012 4:30 am


Return to EtherMega

Who is online

Users browsing this forum: No registered users and 0 guests