DANG SPI!!!!!

I’m working on a project that has a nRF2.4 radio and uses an SD card (adafruit datalogger shield). I know the card is good. I know that the code works without the SD perfectly. When I add the code for the SD card… The code just goes into a loop at “Initializing SD card… card initialized.” Writing it over and over. It writes blank files to the card with no header (“millis,stamp,datetime,light,temp,vcc”), completely blank. How do I fix the dang SPI conflict!? (assuming thats what it is).

Code (Partial to void loop, which it never reaches):

/*
Base only code...
 */

#include <serialGLCDlib.h>
#include <avr/pgmspace.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#include <SD.h>

#define DHTPIN 2 // DHT Pin
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;


#define LOG_INTERVAL 1000
#define SYNC_INTERVAL 1000
uint32_t syncTime = 0;

#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()

const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
//  digitalWrite(redLEDpin, HIGH);

  while(1);
}

// Avoid spurious warnings
#undef PROGMEM 
#define PROGMEM __attribute__(( section(".progmem.data") )) 
#undef PSTR 
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))

RF24 radio(8,9); //Radio pins 3(to8),4(to9)
RF24Network network(radio);

// Our node address
uint16_t this_node;

// The message that we send is just an unsigned int, containing a sensor reading.
struct message_t
{
int temp_reading;
int humid_reading;
int voltage_reading;
int reset_reading;
  message_t(void): temp_reading(0), humid_reading(0), voltage_reading(0), reset_reading(0) {}//ADD VOLTAGE READING!!!!
};

int lcdCount = 0;
int tempf = 0;
int humidrh = 0;
int voltage = 0;
int reset = 0;

char nodereset[10] = "RS";
char nodetemp1[10] = "ND";
char humid1[10] = "ND";
char voltage1[10] = "ND";
char nodetemp2[10] = "ND";
char humid2[10] = "ND";
char voltage2[10] = "ND";
char nodetemp3[10] = "ND";
char humid3[10] = "ND";
char voltage3[10] = "ND";
int nodetemp4 = 0;
int humid4 = 0;
char voltage4[10] = "ND";
char batstat1[14] = "Odr Bat Low!";
char batstat2[14] = "Idr Bat Low!";
char batstat3[14] = "Atc Bat Low!";
char sysStat[13] = "Sys Stus:";
char sysStatc[14] = "All Ok       ";

//-------------------------------------------------------------------------------

void setup(void)
{

  Serial.begin(115200);
  delay(5000);
  

  // Which node are we?
  this_node = 0;
    
  //
  //DHT sensor
  //  

  dht.begin();
  Wire.begin();
  RTC.begin();
  
    // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
  

  logfile.println("millis,stamp,datetime,light,temp,vcc");
  
  //
  // Bring up the RF network
  //

  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 92, /*node address*/ this_node);
}

serialGLCD lcd; // initialisation


//------------------------------------------------------------------------------------

void loop(void)
{
//  lcd.reverseColor();
if ( lcdCount == 0 ){
  lcd.clearLCD();
  
    DateTime now = RTC.now();

The code you posted is incomplete.

Board?

Sorry… It’s a Uno (non R3)

I’m beginning to think that I am running out of memory… I have moved some stuff around and tried to reduce size where I could. The sketch as it appears here is 27090 bytes.

Code in full

/*
Base only code...
 */

#include <serialGLCDlib.h>
#include <avr/pgmspace.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
//#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#include <SD.h>

//#define DHTPIN 2 // DHT Pin
//#define DHTTYPE DHT22   // DHT 22
//DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;

#define P(name) const prog_uchar name[] PROGMEM // declare a PROGMEM string
#define LOG_INTERVAL 1000
#define SYNC_INTERVAL 1000
uint32_t syncTime = 0;


const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
//  digitalWrite(redLEDpin, HIGH);

  while(1);
}

// Avoid spurious warnings
#undef PROGMEM 
#define PROGMEM __attribute__(( section(".progmem.data") )) 
#undef PSTR 
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))

RF24 radio(8,9); //Radio pins 3(to8),4(to9)
RF24Network network(radio);

// Our node address
const int this_node = 0;

// The message that we send is just an unsigned int, containing a sensor reading.
struct message_t
{
int temp_reading;
int humid_reading;
int voltage_reading;
int reset_reading;
  message_t(void): temp_reading(0), humid_reading(0), voltage_reading(0), reset_reading(0) {}//ADD VOLTAGE READING!!!!
};

bool lcdCount = 0;
int tempf = 0;
int humidrh = 0;
int voltage = 0;
int reset = 0;

char nodereset[3] = "RS";
char nodetemp1[4] = "ND";
char humid1[4] = "ND";
char voltage1[4] = "ND";
char nodetemp2[4] = "ND";
char humid2[4] = "ND";
char voltage2[4] = "ND";
char nodetemp3[4] = "ND";
char humid3[4] = "ND";
char voltage3[4] = "ND";
int nodetemp4 = 0;
int humid4 = 0;
P(batstat1) = "Odr Bat Low!";
P(batstat2) = "Idr Bat Low!";
P(batstat3) = "Atc Bat Low!";
P(sysStat) = "Sys Stus:";
P(sysStatc) = "All Ok       ";

//-------------------------------------------------------------------------------

void setup(void)
{

  
//
// Print preamble
//
  
  Serial.begin(115200);
  delay(5000);
  
//
// Pull node address out of eeprom 
//
    
  //
  //DHT sensor
  //  

//  dht.begin();
  Wire.begin();
  RTC.begin();
  
    // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
  

  logfile.println("millis,stamp,datetime,light,temp,vcc");
  
  //
  // Bring up the RF network
  //

  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 92, /*node address*/ this_node);
}

serialGLCD lcd; // initialisation


//------------------------------------------------------------------------------------

void loop(void)
{
//  lcd.reverseColor();
if ( lcdCount == 0 ){
  lcd.clearLCD();
  
    DateTime now;
    
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
// log milliseconds since starting
//uint32_t m = millis();
//logfile.print(m); // milliseconds since start
//logfile.print(", ");

//----------------------- time shit -------------------------------------------

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print("/");
  logfile.print(now.year(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
    
lcd.gotoLine(7);
Serial.print("                     ");
delay(10);
lcd.gotoLine(7);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
Serial.print(now.hour(), DEC);
Serial.print(":");
delay(10);
Serial.print(now.minute(), DEC);
Serial.print(" Now");
    
lcd.gotoLine(8);
Serial.print("                     ");
delay(10);
lcd.gotoLine(8);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
Serial.print(now.hour(), DEC);
Serial.print(":");
delay(10);
Serial.print(now.minute(), DEC);
Serial.print(" Start");
delay(10);
   
// Print title information 
lcd.gotoLine(1);
Serial.print("Local  Temp  RH%  Bat");

lcd.gotoLine(4);
Serial.print("     BOOTING  UP  ");

lcdCount = 1;
}
  
//humid4 = dht.readHumidity();
//int t = dht.readTemperature();
nodetemp4 = (1.8 + 32); //ADD t BACK IN!!!!! 

// Pump the network regularly
  network.update();

  // If we are the base, is there anything ready for us?
  while ( network.available() )
  {
    // If so, grab it and print it out
    RF24NetworkHeader header;
    message_t message;
    network.read(header,&message,sizeof(message));

//------------------- Converting and Storing radio data ---------------------------------

tempf = (message.temp_reading * 1.8 + 32);
humidrh = (message.humid_reading);
voltage = (message.voltage_reading);
reset = (message.reset_reading);

//--------------------Storing Node Number for sorting use -----------------------------------

int nodedump = header.from_node;

//------------------------- Sorting received information from radio ---------------------------

switch(nodedump) // If node dump reads "1" through blah is node. Need to assign Attic, Outdoor, etc. 
{
case 1: // no "0" because we will hard code it in.
itoa(tempf, nodetemp1,4); //converting tempf to nodetemp1 for display and storage
itoa(humidrh, humid1, 4); //converting humidrh to humid1 for display and storage
itoa(voltage, voltage1, 4);
break;
case 2:
humidrh = humidrh - 2; //calibration indoor sensor humid is +2
itoa(tempf, nodetemp2, 4);
itoa(humidrh, humid2, 4);
itoa(voltage, voltage2, 4);
break;
case 3:
humidrh = humidrh - 5; //calibration attic sensor humid is +5
itoa(tempf, nodetemp3, 4);
itoa(humidrh, humid3, 4);
itoa(voltage, voltage3, 4);
break;
default :
break;
}

//------------------------- Battery Warning -------------------------------

if (voltage < 25){
switch(nodedump) 
{
case 1:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
printP(sysStat);
delay(10);
printP(batstat1);
delay(10);
}
break;
case 2:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
printP(sysStat);
delay(10);
printP(batstat2);
delay(10);
}
break;
case 3:
if (voltage < 25){
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
printP(sysStat);
delay(10);
printP(batstat3);
delay(10);
}
break;
default :
break;
}
}
else
{
lcd.gotoLine(6);
Serial.print("                     ");
delay(10);
lcd.gotoLine(6);
printP(sysStat);
delay(10);
printP(sysStatc);
delay(10);
}
//------------------------- Reset -------------------------------

switch(nodedump)
{
case 1:
if(reset == 1){
strcpy(nodetemp1, nodereset);
strcpy(humid1, nodereset);
//sdWrite();
}
break;
case 2:
if(reset == 1){
strcpy(nodetemp2, nodereset);
strcpy(humid2, nodereset);
//sdWrite();
}
break;
case 3:
if(reset == 1){
strcpy(nodetemp3, nodereset);
strcpy(humid3, nodereset);
//sdWrite();
}
break;
default :
break;
}

Continued…

// setting cursor for printing on second line of display...
lcd.gotoLine(2);
Serial.print("                     ");
delay(10);
lcd.gotoLine(2);
Serial.print("Base ");
delay(10);
lcd.gotoPosition(43,8);
Serial.print(nodetemp4);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,8);
Serial.print(humid4);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,8);
Serial.print("A/C");
delay(10);

lcd.gotoLine(3);
Serial.print("                     ");
delay(10);
lcd.gotoLine(3);
Serial.print("Indr ");
delay(10);
lcd.gotoPosition(43,16);
Serial.print(nodetemp2  );
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,16);
Serial.print(humid2);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,16);
Serial.print(voltage2);
delay(10);

lcd.gotoLine(4);
Serial.print("                     ");
delay(10);
lcd.gotoLine(4);
Serial.print("Attc ");
delay(10);
lcd.gotoPosition(43,24);
Serial.print(nodetemp3);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,24);
Serial.print(humid3);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,24);
Serial.print(voltage3);
delay(10);

lcd.gotoLine(5);
Serial.print("                     ");
delay(10);
lcd.gotoLine(5);
Serial.print("Otdr ");
delay(10);
lcd.gotoPosition(43,32);
Serial.print(nodetemp1);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,32);
Serial.print(humid1);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,32);
Serial.print(voltage1);
delay(10);

  logfile.print(", ");
  logfile.print(nodetemp2);
  logfile.print(", ");
  logfile.print(humid2);
  logfile.print(", ");
  logfile.print(nodetemp3);
  logfile.print(", ");
  logfile.print(humid3);
  logfile.print(", ");
  logfile.print(nodetemp1);
  logfile.print(", ");
  logfile.print(humid1);
  
  
  logfile.println();

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
  
  // blink LED to show we are syncing data to the card & updating FAT!
  logfile.flush();
  delay(10);
  
  }
}
//-------------------------------------------------------------------------------------

// function to print a PROGMEM string
void printP(const prog_uchar *str)
{
char c;
while((c = pgm_read_byte(str++)))
Serial.print(c,BYTE);
}

Sorry… It’s a Uno (non R3)

SRAM 2 KB (ATmega328)

I’m beginning to think that I am running out of memory…

Maybe. I count 509 bytes in static strings (you really should be using the F-macro) and 60 bytes in globals. But I don’t know what these add…

RTC_DS1307 RTC;
File logfile;
RF24 radio(8,9); //Radio pins 3(to8),4(to9)
RF24Network network(radio);
serialGLCD lcd; // initialisation

I suggest introducing the F-macro to your sketch to reduce that 509.

Which devices are SPI?

RobDrizzle:
Continued…

// setting cursor for printing on second line of display...

lcd.gotoLine(2);
Serial.print("                     ");
delay(10);
lcd.gotoLine(2);
Serial.print("Base ");
delay(10);
lcd.gotoPosition(43,8);
Serial.print(nodetemp4);
Serial.print(“F “);
delay(10);
lcd.gotoPosition(79,8);
Serial.print(humid4);
Serial.print(”%”);
delay(10);
lcd.gotoPosition(109,8);
Serial.print(“A/C”);
delay(10);

lcd.gotoLine(3);
Serial.print("                     ");
delay(10);
lcd.gotoLine(3);
Serial.print("Indr ");
delay(10);
lcd.gotoPosition(43,16);
Serial.print(nodetemp2  );
Serial.print(“F “);
delay(10);
lcd.gotoPosition(79,16);
Serial.print(humid2);
Serial.print(”%”);
delay(10);
lcd.gotoPosition(109,16);
Serial.print(voltage2);
delay(10);

lcd.gotoLine(4);
Serial.print("                     ");
delay(10);
lcd.gotoLine(4);
Serial.print("Attc ");
delay(10);
lcd.gotoPosition(43,24);
Serial.print(nodetemp3);
Serial.print(“F “);
delay(10);
lcd.gotoPosition(79,24);
Serial.print(humid3);
Serial.print(”%”);
delay(10);
lcd.gotoPosition(109,24);
Serial.print(voltage3);
delay(10);

lcd.gotoLine(5);
Serial.print("                     ");
delay(10);
lcd.gotoLine(5);
Serial.print("Otdr ");
delay(10);
lcd.gotoPosition(43,32);
Serial.print(nodetemp1);
Serial.print(“F “);
delay(10);
lcd.gotoPosition(79,32);
Serial.print(humid1);
Serial.print(”%”);
delay(10);
lcd.gotoPosition(109,32);
Serial.print(voltage1);
delay(10);

logfile.print(", “);
  logfile.print(nodetemp2);
  logfile.print(”, “);
  logfile.print(humid2);
  logfile.print(”, “);
  logfile.print(nodetemp3);
  logfile.print(”, “);
  logfile.print(humid3);
  logfile.print(”, “);
  logfile.print(nodetemp1);
  logfile.print(”, ");
  logfile.print(humid1);
 
 
  logfile.println();

// Now we write data to disk! Don’t sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
 
  // blink LED to show we are syncing data to the card & updating FAT!
  logfile.flush();
  delay(10);
 
  }
}
//-------------------------------------------------------------------------------------

// function to print a PROGMEM string
void printP(const prog_uchar *str)
{
char c;
while((c = pgm_read_byte(str++)))
Serial.print(c,BYTE);
}

You could save a lot of code by sticking your parameters in an array (in ram) and the labels (and lcd screen positions if need be, but better if logic can generate them) in a matching array (in progmem) and looping through to print your results. That includes the delays.

[quote author=Coding Badly link=topic=101003.msg758481#msg758481 date=1334264761]

Which devices are SPI?

[/quote]

SD card is SPI nRF2.4 Radio is SPI RTC is I2C GLCD is serial

I was thinking about having a slave on I2C to handle the nRF radio stuff and then send it over to the master for general processing and logging... lol... It feels like a bad idea but part of me says "yessssssssssssssssssssssssss"

When I add the code for the SD card... The code just goes into a loop at "Initializing SD card... card initialized." Writing it over and over.

The SD library needs a 512 byte buffer to write to the card. That's 1/4 of your memory.

I guess I'm kinda confused about the F macro. I'm already sticking the static strings in progmem... Aren't I? I will also admit that I thought the complied size was the issue... I guess i never really thought about the ram.

So I hear you guys. I really would like to cut down this code but am unsure how I can make the switchcase statements simpler...

GoForSmoke: You could save a lot of code by sticking your parameters in an array (in ram) and the labels (and lcd screen positions if need be, but better if logic can generate them) in a matching array (in progmem) and looping through to print your results. That includes the delays.

Not sure about this. Which parameters are you talking about? And I wouldn't even know where to begin with the lcd positions. :blush:

ok… The amount of ram used by:
dht = 33b
sd = 787b
nRF = 303b

With everything up and running except the nRF the amount of ram free is only 450b

Where can I go from here? With the nRF there is only 147b left. And if I really need 500b for the sd to init then I need to find at least 353b.

Thanks guys.

Revised code with some of the offenders striped out.

/*
Base only code...
 */

#include <serialGLCDlib.h>
//#include <RF24Network.h>
//#include <RF24.h>
#include <SPI.h>
#include "DHT.h"
#include <Wire.h>
#include "RTClib.h"
#include <SD.h>

#define DHTPIN 2 // DHT Pin
#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;

#define SYNC_INTERVAL 15000
uint32_t syncTime = 0;

const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
//  digitalWrite(redLEDpin, HIGH);

  while(1);
}

//RF24 radio(8,9); //Radio pins 3(to8),4(to9)
//RF24Network network(radio);

// Our node address
byte this_node;

// The message that we send is just an unsigned int, containing a sensor reading.
struct message_t
{
int temp_reading;
int humid_reading;
int voltage_reading;
bool reset_reading;
  message_t(void): temp_reading(0), humid_reading(0), voltage_reading(0), reset_reading(0) {}//ADD VOLTAGE READING!!!!
};

bool lcdCount = 0;
int tempf = 0;
int humidrh = 0;
int voltage = 0;
int reset = 0;
int syncSwitch = 0;

int nodetemp1;
int humid1;
int voltage1;
int nodetemp2;
int humid2;
int voltage2;
int nodetemp3;
int humid3;
int voltage3;
int nodetemp4;
int humid4;

//-------------------------------------------------------------------------------

void setup(void)
{

  
//
// Print preamble
//
  
  Serial.begin(115200);
  delay(5000);

  // Which node are we?
  this_node = 0;
    
  //
  //DHT sensor
  //  

  dht.begin();
  Wire.begin();
  RTC.begin();
  
    // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
   if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);

  logfile.println("datetime,BaseTemp,BaseHumid,IndorTemp,IndorHumid,AtticTemp,AtticHumid,OutdrTemp,OutdrHumid");
  
  //
  // Bring up the RF network
  //

  SPI.begin();
//  radio.begin();
//  network.begin(/*channel*/ 92, /*node address*/ this_node);
}

serialGLCD lcd; // initialisation


//------------------------------------------------------------------------------------

void loop(void)
{
  
DateTime now;
  
now = RTC.now();
  
//  lcd.reverseColor();
if ( lcdCount == 0 ){
  lcd.clearLCD();
     
lcd.gotoLine(8);
Serial.print("                     ");
delay(10);
lcd.gotoLine(8);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
Serial.print(now.hour(), DEC);
Serial.print(":");
delay(10);
Serial.print(now.minute(), DEC);
Serial.print(" Start");
delay(10);
   
// Print title information 
lcd.gotoLine(1);
Serial.print("Local  Temp  RH%  Bat");

lcd.gotoLine(4);
Serial.print("     BOOTING  UP  ");

lcdCount = 1;
}

  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print("/");
  logfile.print(now.year(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
 
  
humid4 = dht.readHumidity();
int t = dht.readTemperature();
nodetemp4 = (t * 1.8 + 32);
  
  // Pump the network regularly
//  network.update();

  // If we are the base, is there anything ready for us?
//  while ( network.available() )
  {
    // If so, grab it and print it out
//    RF24NetworkHeader header;
    message_t message;
 //   network.read(header,&message,sizeof(message));

//------------------- Converting and Storing radio data ---------------------------------

tempf = (message.temp_reading * 1.8 + 32);
humidrh = (message.humid_reading);
voltage = (message.voltage_reading);
reset = (message.reset_reading);

//--------------------Storing Node Number for sorting use -----------------------------------

byte nodedump = 0; //header.from_node; //!!!!!!!!!!!!!!!!

//------------------------- Sorting received information from radio ---------------------------

switch(nodedump) // If node dump reads "1" through blah is node. Need to assign Attic, Outdoor, etc. 
{
case 1: // no "0" because we will hard code it in.
nodetemp1 = tempf; //converting tempf to nodetemp3 for display and storage
humid1 = humidrh; //converting humidrh to humid3 for display and storage
voltage1 = voltage;
break;
case 2:
humidrh = humidrh - 2; //calibration indoor sensor humid is +2
nodetemp2 = tempf;
humid2 = humidrh;
voltage2 = voltage;
break;
case 3:
humidrh = humidrh - 5; //calibration attic sensor humid is +5
nodetemp3 = tempf;
humid3 = humidrh;
voltage3 = voltage;
break;
default :
break;
}

//------------------------- Reset -------------------------------

switch(nodedump)
{
case 1:
if(reset == 1){
nodetemp1 = 0;
humid1 = 0;
syncSwitch = 1;
sdWrite();
}
break;
case 2:
if(reset == 1){
nodetemp2 = 0;
humid2 = 0;
syncSwitch = 1;
sdWrite();
}
break;
case 3:
if(reset == 1){
nodetemp3 = 0;
humid3 = 0;
syncSwitch = 1;
sdWrite();
}
break;
default :
break;
}

//------------------------ Data to SD ---------------------------

logfile.print(", ");
logfile.print(nodetemp4);
logfile.print(", ");
logfile.print(humid4);
logfile.print(", ");
logfile.print(nodetemp2);
logfile.print(", ");
logfile.print(humid2);
logfile.print(", ");
logfile.print(nodetemp3);
logfile.print(", ");
logfile.print(humid3);
logfile.print(", ");
logfile.print(nodetemp1);
logfile.print(", ");
logfile.print(humid1);
logfile.println();

and

// setting cursor for printing on second line of display...
lcd.gotoLine(2);
Serial.print("                     ");
delay(10);
lcd.gotoLine(2);
Serial.print("Base ");
delay(10);
lcd.gotoPosition(43,8);
Serial.print(nodetemp4);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,8);
Serial.print(humid4);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,8);
Serial.print("A/C");
delay(10);

lcd.gotoLine(3);
Serial.print("                     ");
delay(10);
lcd.gotoLine(3);
Serial.print("Indr ");
delay(10);
lcd.gotoPosition(43,16);
Serial.print(nodetemp2  );
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,16);
Serial.print(humid2);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,16);
Serial.print(voltage2);
delay(10);

lcd.gotoLine(4);
Serial.print("                     ");
delay(10);
lcd.gotoLine(4);
Serial.print("Attc ");
delay(10);
lcd.gotoPosition(43,24);
Serial.print(nodetemp3);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,24);
Serial.print(humid3);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,24);
Serial.print(voltage3);
delay(10);

lcd.gotoLine(5);
Serial.print("                     ");
delay(10);
lcd.gotoLine(5);
Serial.print("Otdr ");
delay(10);
lcd.gotoPosition(43,32);
Serial.print(nodetemp1);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,32);
Serial.print(humid1);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,32);
Serial.print(voltage1);
delay(10);

//----------------------- time shit -------------------------------------------
now = RTC.now();

lcd.gotoLine(6);
Serial.print(memoryFree()); // print the free memory
    
lcd.gotoLine(7);
Serial.print("                     ");
delay(10);
lcd.gotoLine(7);
Serial.print(now.month(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.day(), DEC);
Serial.print("/");
delay(10);
Serial.print(now.year(), DEC);
Serial.print(" ");
delay(10);
Serial.print(now.hour(), DEC);
Serial.print(":");
delay(10);
Serial.print(now.minute(), DEC);
Serial.print(" Now");

if ((millis() - syncTime) < SYNC_INTERVAL){
syncSwitch = 1;
syncTime = millis();
sdWrite();
  }
  }
}
//-------------------------------------------------------------------------------------

void sdWrite()
{
  
    // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if (syncSwitch = 1) return;
  syncSwitch = 0;
  
  // blink LED to show we are syncing data to the card & updating FAT!
  logfile.flush();
  
}

// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree()
{
int freeValue;
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}

RobDrizzle:
I guess I’m kinda confused about the F macro. I’m already sticking the static strings in progmem… Aren’t I?

Nope, not at all. Every Serial.print (or println) line needs to have the F macro explicitly used.

Looks like if you follow Coding Badly’s advice you’ll find your 500 bytes.

See http://arduino.cc/en/Main/ReleaseNotes for more info. Oh yeah, make sure you add the line

#include <avr/pgmspace.h>

Before you try to use the macro.

Hope this helps,

Brad

Sorry this took so long, you might have gotten past some of it.

Don't know where to begin?

See where you have the comment Time Shit? Below that over and over you have the same basic lines of code with very little changed. You begin by seeing what is the same or almost the same and thinking up how to generalize it.

Elements (chars, ints, structs, unions) in an array all address through indexes. I can have a dozen separate variables all the same type and a dozen blocks of code to do the same basic thing to each one by name, or, I can put them all in an array and loop the bunch through one block of code that takes care of them all as a matter of rule. I can have exceptions even, that's what if() statements are for. But the better my solution, the fewer of that kind of thing it will need.

If it's any consolation, I have fixed bug-ridden code written by a PhD in the early 80's who didn't know that. Maybe they teach it since then but not everywhere. In 88 and 89 I saw four Drexel U CompSci Masters that weren't a whole lot brighter when it came to code. They had this attitude that newer computers would cover bad habits. It frankly amazed me that people who could get through calculus didn't generalize their code.

Anyway, blocks like this:

// setting cursor for printing on second line of display...
lcd.gotoLine(2);
Serial.print("                     ");
delay(10);
lcd.gotoLine(2);
Serial.print("Base ");
delay(10);
lcd.gotoPosition(43,8);
Serial.print(nodetemp4);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,8);
Serial.print(humid4);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,8);
Serial.print("A/C");
delay(10);

lcd.gotoLine(3);
Serial.print("                     ");
delay(10);
lcd.gotoLine(3);
Serial.print("Indr ");
delay(10);
lcd.gotoPosition(43,16);
Serial.print(nodetemp2  );
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,16);
Serial.print(humid2);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,16);
Serial.print(voltage2);
delay(10);

lcd.gotoLine(4);
Serial.print("                     ");
delay(10);
lcd.gotoLine(4);
Serial.print("Attc ");
delay(10);
lcd.gotoPosition(43,24);
Serial.print(nodetemp3);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,24);
Serial.print(humid3);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,24);
Serial.print(voltage3);
delay(10);

lcd.gotoLine(5);
Serial.print("                     ");
delay(10);
lcd.gotoLine(5);
Serial.print("Otdr ");
delay(10);
lcd.gotoPosition(43,32);
Serial.print(nodetemp1);
Serial.print("F ");
delay(10);
lcd.gotoPosition(79,32);
Serial.print(humid1);
Serial.print("%");
delay(10);
lcd.gotoPosition(109,32);
Serial.print(voltage1);
delay(10);

What's that, like 4 times over almost the same thing? What is different that the difference can't be held in data? Lcd positions? Are data. What variable name? With arrays, the name is the same and the index is... data.

As I wrote above: I can put them all in an array and loop the bunch through one block of code that takes care of them all as a matter of rule. I can have exceptions even, that's what if() statements are for. But the better my solution, the fewer of that kind of thing it will need.

That whole mess above can be reduced to less than 20 lines just by organizing the data and coding for it.

There is further reduction aimed at reducing ram use possible and so many ways to approach I won't even start. Just look at where you store things and ask if you have to then find ways to not have to. At some point the task will be reduced to what it has to do but until then it's fat.

Am I going to do it for you? I'd rather you did the thinking for yourself, it's the best way to learn. It will give you conceptual tools you won't get if someone does it for you and you can pick up a few tricks you wouldn't have otherwise and actually understand them having made them yourself.

I see things like this:

char nodereset[10] = "RS";
char nodetemp1[10] = "ND";
char humid1[10] = "ND";
char voltage1[10] = "ND";
char nodetemp2[10] = "ND";
char humid2[10] = "ND";
char voltage2[10] = "ND";
char nodetemp3[10] = "ND";
char humid3[10] = "ND";
char voltage3[10] = "ND";

I take it that from nodereset[] to voltage[] are where you prepare strings for printing out? There's 9 different 10 character buffers right there alone. One for each variable. How PC!

It would be better by far to use as few buffers as you can get away with. The same -one- buffer for each in turn, that you can copy PROGMEM constant strings into or use itoa() or sprintf() to fill. You really only need ONE since you only print ONE out at a time. It should be long enough to handle anything you print within reason (maybe 20 or 32 to 40 chars?) but unless you have to have two for some odd reason then ONE is enough.

======================================================================================

Think about it this way. You need to set a table for 12 guests. Do you go and get all the plates, bowls, silverware and drinking glasses at once and then set them on the table? You might, if you had a big enough dish cart. But if you've only got your two hands then you get some of the things, set them in place and then more, until you're done. Now suppose the real task is to feed 12 people but you're so used to everyone at the table at once you don't think hey, wait, I don't even need the big table. Instead, you're out looking for a big dish cart.

Thanks guys...

I wasn't at all fishing for someone to do it for me. The information on F() is kinda scarse and I was (still kinda am) having trouble finding a good read up on how to properly use it.

I am looking at the repeated code blocks and trying to get it down to a reasonable size.

Besides learning the programming for the arduinos, the last programming software I learned was Fortran... Lol, just to date myself! So I'm still trying to grasp all the ins and outs.

Just take it a step at a time and I hope you have time for this project to work out. Haven't touched Fortran since 75 when we punched cards. That was my first programming course.