uploading error

Hello Forum (for the first time),

I am trying to do something very simple but have run into a problem that I cannot figure out. I have adapted Ovidiu Predescu’s TinyWebServer to build a internet-based door opener for our chicken coop. Everything works great and it is ready to be installed.

I also want to be able to measure the temperature inside the coop and report it when I make an http request. I’ve added a DS18B20 sensor on digital pin 8 and run the sample sketch provided with the OneWire library and it runs fine.

The problem comes when I combine the two sketches I get the following message:

Problem uploading to board.
Binary sketch size: 31320 bytes (of a 32256 byte maximum)
avrdude: stk500_recv(): programmer is not responding

I thought it was a size issue because I have read here on the forums that the actual maximum is lower than 32256 but I have made the sketch smaller (by taking out the file upload routine from TinyWebServer) and had the same issue. The code below is a version that has the OneWire code integrated into the temp_handler routine but I have also written it using a separate routine that returns a float. That version fails only when I call the OneWire routine from within the temp_handler.

Anyone have any ideas? It is getting to be well below -18 C here at night and I am tired of manually running out to close the coop door so I would like to get this thing installed soon!

You help will be much appreciated.

-Micah

p.s.- My code was longer that 9500 characters so I deleted the routines that were unchanged (or only minor changes ) from Ovidiu’s blink_led sketch.

// Chicken Coop 2.1

#include <SPI.h>
#include <Ethernet.h>
#include <Flash.h>
#include <SD.h>
#include <TinyWebServer.h>
#include <OneWire.h>

//Temperature chip i/o
OneWire ds(8); // on digital pin 8

// The LED attached in PIN 13 on an Arduino board.
const int ledPin = 7;
const int motor1Pin = 5;    // H-bridge leg 1 (pin 2, 1A)
const int motor2Pin = 6;    // H-bridge leg 2 (pin 7, 2A)
const int enablePin = 9;    // H-bridge enable pin

void activateMotor(boolean state) {
    ledState = state;
// set enablePin high so that motor can turn on:
      digitalWrite(enablePin, HIGH);

// Go up if ledState is low, go down of LED state is High
 if (ledState == 0) {
     digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge low
     digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge high
     delay(4800);
     Serial.println("DONE-1");
    } 
    // if the switch is low, motor will turn in the other direction:
    else {
      digitalWrite(motor1Pin, LOW);  // set leg 1 of the H-bridge high
      digitalWrite(motor2Pin, HIGH);   // set leg 2 of the H-bridge low  
      delay(4200);
      Serial.println("DONE-2");
    }
// turn off the H-Bridge to stop the motor
    
      digitalWrite(enablePin, LOW);
      Serial.println("DONE-3");
}

inline boolean getLedState() { return ledState; }

boolean file_handler(TinyWebServer& web_server);
boolean blink_led_handler(TinyWebServer& web_server);
boolean led_status_handler(TinyWebServer& web_server);
boolean index_handler(TinyWebServer& web_server);
boolean temp_handler(TinyWebServer& web_server);

TinyWebServer::PathHandler handlers[] = {
  // Micah put in the 'temp_handler'
  {"/", TinyWebServer::GET, &index_handler },
  {"/upload/" "*", TinyWebServer::PUT, &TinyWebPutHandler::put_handler },
  {"/blinkled", TinyWebServer::POST, &blink_led_handler },
  {"/temp", TinyWebServer::GET, &temp_handler },
  {"/ledstatus" "*", TinyWebServer::GET, &led_status_handler },
  {"/" "*", TinyWebServer::GET, &file_handler },
  {NULL},
};


// TEMP HANDLER - Micah
boolean temp_handler(TinyWebServer& web_server) {
  web_server.send_error_code(200);
  web_server.end_headers(); 
  
  // Minimal Temp stuff from OneWire example
  
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return false;
  }
 
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return false;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return false;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  
  
  web_server << F("<html><body><h1>Hello Micah, the Temperature is </h1></body></html>\n"); 
  return true;
}

"programmer not responding" is unlikely to be because of your sketch (unless it's size, but you already checked that). Instead, it's likely to be a computer configuration or a cabling problem. Did you pull the power from the board, re-seat the cables, re-start your computer, and try again? Can you upload another sketch (such as blink)?

jwatte: Can you upload another sketch (such as blink)?

Yes, I can go back and forth between working and non-working versions. I've stepped through the program commenting the temperature routine back in line-by-line and any time I make a call to a OneWire function, I get that error.

From the symptoms, the only mechanism I can guess at is that the bootloader is corrupting its own memory, but I can't imagine why a trivial change to the code would cause that. Are you certain you've got the correct board type selected?

Binary sketch size: 31320 bytes (of a 32256 byte maximum)

I thought the bootloaders on all chips with more than 8 kB of flash was 2KB, not 512B? The 32256 maximum is 32768-512, and I think the bootloader size is incorrectly calculated here. The real maximum for a 32KB chip should be 30720 bytes if this is the case. So, can you add OneWire use to your sketch without exceeding 30720 bytes in size, and try that? Perhaps remove some other code, or some strings if you're using Serial print?