Go Down

Topic: is my program too large? (Read 566 times) previous topic - next topic

My program size is 12,550 bytes of the 14,336 maximum for a pro mini 168. It uploads fine but either prints garbage to the lcd or nothing at all.  When i cut the program size to about 10,700 bytes by removing the Onewire Library, the sketch works fine.  I had the same sketch running on a 328 with no problems. If it is an issue of program size, why would I be able to upload it in the first place? Any suggestions to shrink the size?

Code: [Select]
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#define rxpin 12
#define txpin 11 

SoftwareSerial mySerial(rxpin, txpin);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

const int numReadings = 3;
const int sensorPin = A5;
const int pumpPin = 9;
const int ledPin1 = 8;
const int ledPin2 = 13;
const int sensorMin = 0;      // sensor minimum, discovered through experiment
const int sensorMax = 1023;
const unsigned int MAX_INPUT = 50;
float readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
float total = 0;                  // the running total
float average = 0;
int sensorValue = 0;
int DS18S20_Pin = 10;
float pHtarget = 5.8;
float pHhigh = pHtarget + .05;
float pHlow = pHtarget - .05;
float phValue = 0;
OneWire ds(DS18S20_Pin);



void setup()
{
  lcd.begin(16, 2);
  lcd.print ("pH start");
  delay(200);
  Serial.begin(38400);
  mySerial.begin(38400);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
  //getTemp();
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;

}

void process_average (float average)
{
lcd.clear();
  Serial.println(average);
  lcd.print ("pH value:");
  lcd.setCursor(12, 0); // top right
  lcd.print(average);
  Serial.println ("phValue");

  if (average > pHhigh)
  {
    lcd.setCursor(0, 0); // top left
    lcd.print("ph adjust:");
    lcd.setCursor(0, 1); // bottom left
    lcd.print("Too High");
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin1, HIGH);
    digitalWrite(pumpPin, HIGH);
    delay(150);
    digitalWrite(pumpPin, LOW);
    digitalWrite(ledPin1, LOW);
    delay(10000);
    lcd.clear();
  }

  else if (average  < pHlow)
  {
    digitalWrite(ledPin2, LOW);
    digitalWrite(ledPin1, HIGH);
    lcd.setCursor(0, 1); // bottom left
    lcd.print("Too Low");
    delay (400);
    lcd.clear();
  }
  else
  {
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin1, LOW);
    Serial.println(average);
   
    delay(400);
    lcd.clear();
  }
}
void loop(){

  total= total - readings[index];   // subtract the last reading:     

  mySerial.print("r");
  mySerial.print('\r');
  delay (500);

  readings[index] = getPH (); // read from the sensor:


  total= total + readings[index]; // add the reading to the total:     

  index = index + 1;          // advance to the next position in the array:         


  if (index >= numReadings)          // if we're at the end of the array...   

    index = 0;    // ...wrap around to the beginning:                       


  average = total / numReadings;  // calculate the average:       

  process_average (average);         // send it to the computer as ASCII digit     

  sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue);
  int range = map(sensorValue, sensorMin, sensorMax, 0, 9);
  delay(500);
  switch (range) {
  case 0:                                 //0-102
    break;
  case 1:                                // 54k ohm - 175
    mySerial.print("r");
    mySerial.print('\r');
    lcd.print("Reading Probe...");
    delay(500);
    lcd.clear();
    break;
  case 2:    // 205-306
    break;
  case 3:    // 307-409 18.5k ohm 378
    lcd.print("Calibration:");
    lcd.setCursor(0,2);
    lcd.print("SEVEN-equalizing");
    mySerial.print("c");
    mySerial.print('\r');
    delay (60000);
    lcd.clear();
    mySerial.print("s");
    mySerial.print('\r');
    lcd.print("Cal. SEVEN");
    delay(500);
    lcd.clear();
    lcd.print("Switch Buffers");
    delay(10000);
    lcd.clear();
    lcd.print("Calibration:");
    lcd.setCursor(0,2);
    lcd.print("FOUR-equalizing");
    delay (60000);
    mySerial.print("f");
    mySerial.print('\r');
    lcd.print("Cal. FOUR");
    delay(500);
    lcd.clear();       
    lcd.print("Calibration:");
    lcd.setCursor(0,2);
    lcd.print("COMPLETE");
    delay(500);
    lcd.clear();
    mySerial.print("e");
    mySerial.print('\r');
    break;
  case 4:    // 410-511
    break;
  case 5:    // 512-613 8.5k ohm 579
    mySerial.print("e");
    mySerial.print('\r');
    lcd.print("exit");
    delay(500);
    lcd.clear();
    break;
  case 6:    // 614-716 5.5k ohm 682

    break;

  case 7:    // 717-818 3k ohm 807

      break;
  case 8:    // 819-920 1.2k ohm 913
    break; // end of case 8
  case 9:    // 921-1023 0 ohm
    break;

  }

}// end of main loop

float getPH ()
{
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  while (mySerial.available () > 0)
  {
    char inByte = mySerial.read ();

    switch (inByte)
    {

    case '\r':   // end of text                 
      {
        input_line [input_pos] = 0;  // terminating null byte
        char * val (input_line);
        input_pos = 0;// reset buffer for next time
        Serial.println ( val);
        float phValue = atof(val);
        return phValue;


        break;
      }

    case '\n':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;
    }  // end of switch
  }  // end of incoming data
}  // end of function



float getTemp()//returns the temperature from one DS18S20 in DEG Celsius
{
  byte data[12];
  byte addr[8];
  if ( !ds.search(addr)) //no more sensors on chain, reset search
  { 
    ds.reset_search();
    return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7])
  {
    Serial.print("CRC is not valid!\n");
    return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28)
  {
    Serial.print("Device is not recognized");
    return -1000;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  byte present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE); // Read Scratchpad
  for (int i = 0; i < 9; i++)
  { // we need 9 bytes
    data[i] = ds.read();
  }
  ds.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  mySerial.print (TemperatureSum);
  float temp_F = TemperatureSum * 9 / 5 + 32;
 
  lcd.print ("Temp Reading:");
  lcd.setCursor(0, 1); // bottom lef
  lcd.print (temp_F);

  delay (750);
  lcd.clear();

}

AWOL

It's more likely a shortage of RAM issue than program size.
You could try moving some of the constant strings into PROGMEM.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Coding Badly


The string constants are probably exceeding available SRAM.  Try using the F-macro so they are only stored in Flash...

[font=Courier New]  lcd.print ( F( "pH start" ) );[/font]

...repeat for all prints.

Quote
The string constants are probably exceeding available SRAM.  Try using the F-macro so they are only stored in Flash...

lcd.print ( F( "pH start" ) );

...repeat for all prints.
Solved It! However, you said for all prints and when I try to do it for a variable like: lcd.print (F(value)); i get an error that says initializer fails to determine size of '__c'. Is that expected?

AWOL

Quote
when I try to do it for a variable

Variables don't and cannot go in program memory.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.


luxxtek

See http://jeelabs.org/2011/05/22/atmega-memory-use/ to find out how much free ram you have.

Works perfectly, I include this code in all large sketches.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy