basic blinking LED doesn't work once ethernet is initialized

Hey all,

I have a "technical computer science" background but I am new to the arduino world and need your help. I have an arduino uno and an 28J60 Ethernet module attached to it. I am working on a Mac with IDE 1.0.6

I already reduced my "project" to a very basic test but still there I dont understand what happens. THe code below works fine, I have a blinking LED. Once I initialize the Ether28J60 (Line 19; the bold comment) the LED stops blinking. Can someone explain that behaviour? I also tried using the EtherCard library to do the same and also there the same issue. once I initialize the Ethernet the LED doesn't blink anymore.

Many thanks in advance

#include "etherShield.h"
#include "ETHER_28J60.h"
const int ledPin = 13; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED

static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};
static uint8_t ip[4] = {192, 168, 178, 179};
static uint16_t port = 80;

ETHER_28J60 e;

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
**//e.setup(mac, ip, port); **
}

void loop()
{
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
delay(500);
}

The Ethernet shield uses pin 13 for its own purposes. See http://jeelabs.net/pub/docs/ethercard/
Try putting the LED on another pin.

OK I am back at the point where the (for me) "curious" things happen.
Does anyone know how much data I can "respond" via that ethernet library?

I start writing to the ethernet-library like this

e.print("\r\n");

and once I finished "printing" the html I like; I write the response to the client like this

e.respond();

but if I am writing to much the server reacts completely weird. The example below works but if I just add one character e.g. in column 35 the server hangs up.

thanks again

#include "etherShield.h"
#include "ETHER_28J60.h"

int outputPin = 6;

static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};
static uint8_t ip[4] = {192, 168, 178, 179};
static uint16_t port = 80;

ETHER_28J60 e;

void setup()
{
e.setup(mac, ip, port);
pinMode(outputPin, OUTPUT);
Serial.begin(57600);
}

void loop()
{
char* params;

int sensorValue = analogRead(A0);
float humidityPerCent = 100-(sensorValue /10.23);
int nLevelValue1 = int(humidityPerCent);
int nBoundaryLow = 40;
int nBoundaryHigh = 60;
String sHTMLLevelValue1 = "<div class="level ";

if (nLevelValue1 < nBoundaryLow or nLevelValue1 > nBoundaryHigh)
{sHTMLLevelValue1 += "bad";}
sHTMLLevelValue1 += "" style="width:" + String(nLevelValue1) + "%;">" + String(nLevelValue1) +"% <span style="color:#888;"> =>";

if(sensorValue > nBoundaryHigh)
sHTMLLevelValue1 += " the soil is too humid you should";//" the soil is too humid you shouldn't water it!";
// else if(sensorValue < nBoundaryLow)
// sHTMLLevelValue1 += " the soil is too dry you should water it!\r\n";
// else
// sHTMLLevelValue1 += " that seems to be good!\r\n";
sHTMLLevelValue1 += "";
char output[sHTMLLevelValue1.length()+1];
sHTMLLevelValue1.toCharArray(output,sHTMLLevelValue1.length()+1);

//Serial.println(output);
if (params = e.serviceRequest())
{
e.print("\r\n");
e.print("\r\n");
e.print(" \r\n");
e.print(" The Garduino\r\n");
e.print(" \r\n");
e.print(" body, input, select, textarea\r\n");
e.print(" {color: #888;font: 16pt "Source Sans Pro", sans-serif; width: 75%; margin:0 auto;}\r\n");
e.print(" .level{}\r\n");
e.print(" .level.bad{color: red}\r\n");
e.print("\r\n");
e.print("\r\n\r\n");
e.print( output );
// e.print(sensorValue);

if (strcmp(params, "?cmd=on") == 0)
{
digitalWrite(outputPin, HIGH);
e.print("actually watering: stop watering
");
}
else if (strcmp(params, "?cmd=off") == 0) // Modified -- 2011 12 15 # Ben Schueler
{
digitalWrite(outputPin, LOW);
e.print(" start watering");
}
e.print(" \r\n");
e.print("\r\n");
e.respond();
}
}

You are wasting memory using the String class.

You are unnecessarily wasting memory by allowing all those string literals to be copied into SRAM. Stop that by using the F() macro:
e.print(F(" start watering"));

OK does that mean, that it seems that my SRAM is full somewhen and that's why the output starts getting weired?

Thanks for the hint with the memory, but I can't get the F() macro running. I keep getting the error as follows:

error: invalid conversion from 'const __FlashStringHelper*' to 'int'
error: initializing argument 1 of 'void ETHER_28J60::print(int)'

I don't even understand where there should be a conversion to int?

I would appreciate any help.

THX

but I can't get the F() macro running

Show us the code, not just the error messages.

it is exactly what PaulS showed..

#include "etherShield.h"
#include "ETHER_28J60.h"

int outputPin = 6;

static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};                                                     
static uint8_t ip[4] = {192, 168, 178, 179};
static uint16_t port = 80;

ETHER_28J60 e;

void setup()
{ 
  e.setup(mac, ip, port);
  pinMode(outputPin, OUTPUT);
  Serial.begin(57600);
}

void loop()
{
    char* params;
 
    int sensorValue = analogRead(A0);
    float humidityPerCent = 100-(sensorValue /10.23);
    int nLevelValue1 = int(humidityPerCent);
    int nBoundaryLow = 40;
    int nBoundaryHigh = 60;
    String sHTMLLevelValue1 = "<div class=\"level ";
      
      if (nLevelValue1 < nBoundaryLow or nLevelValue1 > nBoundaryHigh)
        	{sHTMLLevelValue1 += "bad";}
      sHTMLLevelValue1 += "\" style=\"width:" + String(nLevelValue1) + "%;\">" + String(nLevelValue1) +"% <span style=\"color:#888;\"> =>";

    if(sensorValue > nBoundaryHigh)
      sHTMLLevelValue1 += " the soil is too humid you should";//" the soil is too humid you shouldn't water it!";
//    else if(sensorValue < nBoundaryLow)
//           sHTMLLevelValue1 += " the soil is too dry you should water it!\r\n";
//         else
//           sHTMLLevelValue1 += " that seems to be good!\r\n";
      sHTMLLevelValue1 += "</span></div>";
      char output[sHTMLLevelValue1.length()+1];
      sHTMLLevelValue1.toCharArray(output,sHTMLLevelValue1.length()+1);

//Serial.println(output);
  if (params = e.serviceRequest())
  {
    e.print("<!DOCTYPE HTML>\r\n");
    e.print("<html>\r\n");
    e.print("	<head>\r\n");
    e.print("		<title>The Garduino</title>\r\n");
    e.print("	<style>\r\n");
    e.print("		body, input, select, textarea\r\n");
    e.print("		{color: #888;font: 16pt \"Source Sans Pro\", sans-serif; width: 75%; margin:0 auto;}\r\n");
    e.print("		.level{}\r\n");
    e.print("		.level.bad{color: red}\r\n");
    e.print("</style>\r\n");
    e.print("</head>\r\n<body>\r\n");
    e.print( output );    
//    e.print(sensorValue);
    
    if (strcmp(params, "?cmd=on") == 0)
    {
      digitalWrite(outputPin, HIGH);
      e.print("actually watering: <A HREF='?cmd=off'>stop watering</A>");
    }
    else if (strcmp(params, "?cmd=off") == 0) // Modified -- 2011 12 15 # Ben Schueler
    {
      digitalWrite(outputPin, LOW);
      e.print(F(" <A HREF='?cmd=on'>start watering</A>"));
    }
    e.print("	</body>\r\n");
    e.print("</html>\r\n");
    e.respond();
  }
}

"I'm running out of memory" and

    String sHTMLLevelValue1 = "<div class=\"level ";

do NOT belong in the same post.

You still have not defined what "can't get it working" means. "It's broke; fix it" has never worked, and never will.

Dear Paul,

I absolutely agree with you that "it's broken; fix it" never will work, but I exactly wrote what the problem is.

dec 13th:
The example below works but if I just add one character e.g. in column 35 the server hangs up.

then the answer was that I am wasting memory and I should try the F() macro what I did but then I started getting the folowing error

dec 16th:
error: invalid conversion from 'const __FlashStringHelper*' to 'int'
error: initializing argument 1 of 'void ETHER_28J60::print(int)'

Let me know what I didn't explained or what I might clarify to get helped.

Many thanks in advance

Let me know what I didn't explained or what I might clarify to get helped.

Changes to code have been suggested. No proof that the changes were made in exactly the way expected has been presented. Post your current code!

If you are getting compiler errors with code you haven't posted, you can't realistically expect us to help.

1704eu, please read #7 below on how to use code boxes. Bottom is an example of using the F() macro to save memory.

http://forum.arduino.cc/index.php/topic,148850.0.html

Below is an example of a web page bundled in a single F() macro. Bundling like this can be broken into parts if variables need to be printed in the page.

//example of web page bundled in single F() macro
//get submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html or use a '
//address will look like http://192.168.1.102:84 when submitted
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString;

//////////////////////

void setup(){

 pinMode(5, OUTPUT); //pin selected to control
 pinMode(6, OUTPUT); //pin selected to control
 pinMode(7, OUTPUT); //pin selected to control
 pinMode(8, OUTPUT); //pin selected to control
 //start Ethernet
 Ethernet.begin(mac, ip, gateway, gateway, subnet);
 server.begin();

 //enable serial data print
 Serial.begin(9600);
 Serial.println(F("server text box test1")); // so I can keep track of what is loaded
}

void loop(){
 // Create a client connection
 EthernetClient client = server.available();
 if (client) {
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();

       //read char by char HTTP request
       if (readString.length() < 100) {

         //store characters to string
         readString += c;
         //Serial.print(c);
       }

       //if HTTP request has ended
       if (c == '\n') {

         ///////////////
         Serial.println(readString); //see what was captured

         //now output HTML data header

client.print(F(  //start F() macro
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
"<HTML>"
"<HEAD>"
"<meta name='apple-mobile-web-app-capable' content='yes' />"
"<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"
"<TITLE>JAVA Page</TITLE>"
"</HEAD>"
"<BODY>"
"<H1>JAVA</H1>"
"<hr />"
"
"
"<FORM ACTION='/' method=get >"
"Enter Code: <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'>
"
"
"
"<input type=submit value='5 ON' style=width:100px;height:45px onClick=location.href='/?on8;'><input type=submit value='5 OFF' style=width:100px;height:45px onClick=location.href='/?off9;'>
"
"<input type=submit value='6 ON' style=width:100px;height:45px onClick=location.href='/?on8;'><input type=submit value='6 OFF' style=width:100px;height:45px onClick=location.href='/?off9;'>
"
"<input type=submit value='7 ON' style=width:100px;height:45px onClick=location.href='/?on8;'><input type=submit value='7 OFF' style=width:100px;height:45px onClick=location.href='/?off9;'>
"
"<input type=submit value='8 ON' style=width:100px;height:45px onClick=location.href='/?on8;'><input type=submit value='8 OFF' style=width:100px;height:45px onClick=location.href='/?off9;'>
"
"</FORM>"
"</BODY>"
"</HTML>"
));   //end F() macro

         delay(1);
         //stopping client
         client.stop();

         /////////////////////
         if(readString.indexOf("5") >0)//checks for on
         {
           digitalWrite(5, HIGH);    // set pin 5 high
           Serial.println(F("Led On"));
         }
         if(readString.indexOf("50") >0)//checks for off
         {
           digitalWrite(5, LOW);    // set pin 5 low
           Serial.println(F("Led Off"));
         }
         
         if(readString.indexOf("6") >0)//checks for on
         {
           digitalWrite(6, HIGH);    // set pin 6 high
           Serial.println(F("Led 6 On"));
         }
         if(readString.indexOf("60") >0)//checks for off
         {
           digitalWrite(6, LOW);    // set pin 6 low
           Serial.println(F("Led 6 Off"));
         }
         
         if(readString.indexOf("7") >0)//checks for on
         {
           digitalWrite(7, HIGH);    // set pin 7 high
           Serial.println(F("Led On"));
         }
         if(readString.indexOf("70") >0)//checks for off
         {
           digitalWrite(7, LOW);    // set pin 7 low
           Serial.println(F("Led Off"));
         }
         
         if(readString.indexOf("8") >0)//checks for on
         {
           digitalWrite(8, HIGH);    // set pin 8 high
           Serial.println(F("Led On"));
         }
         if(readString.indexOf("80") >0)//checks for off
         {
           digitalWrite(8, LOW);    // set pin 8 low
           Serial.println(F("Led Off"));
         }
         //clearing string for next read
         readString="";

       }
     }
   }
 }
}

Hey guys,

Happy New Year! I am back with much more understanding for the whole topic but the same problem. As mentioned, I am having an 28J60 Ethernet module and the following code, where I try to write one line to the flash memory to avoid SRAM overflows. What I got working on a W5100 Shield (the F() macro) is not working with my 28J60 Library.

Is there another method bringing the variables to the flash? If not does anyone know a better library supporting the F() macro?

Many thanks in advance

Benni

#include "etherShield.h"
#include "ETHER_28J60.h"

int outputPin = 6;

static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24};                                                     
static uint8_t ip[4] = {192, 168, 178, 179};
static uint16_t port = 80;

ETHER_28J60 e;

void setup()
{ 
  e.setup(mac, ip, port);
  pinMode(outputPin, OUTPUT);
  Serial.begin(57600);
}

void loop()
{
    char* params;
 
    int sensorValue = analogRead(A0);
    float humidityPerCent = 100-(sensorValue /10.23);
    int nLevelValue1 = int(humidityPerCent);
    int nBoundaryLow = 40;
    int nBoundaryHigh = 60;
    String sHTMLLevelValue1 = "<div class=\"level ";
      
      if (nLevelValue1 < nBoundaryLow or nLevelValue1 > nBoundaryHigh)
        	{sHTMLLevelValue1 += "bad";}
      sHTMLLevelValue1 += "\" style=\"width:" + String(nLevelValue1) + "%;\">" + String(nLevelValue1) +"% <span style=\"color:#888;\"> =>";

    if(sensorValue > nBoundaryHigh)
      sHTMLLevelValue1 += " the soil is too humid you should";//" the soil is too humid you shouldn't water it!";
//    else if(sensorValue < nBoundaryLow)
//           sHTMLLevelValue1 += " the soil is too dry you should water it!\r\n";
//         else
//           sHTMLLevelValue1 += " that seems to be good!\r\n";
      sHTMLLevelValue1 += "</span></div>";
      char output[sHTMLLevelValue1.length()+1];
      sHTMLLevelValue1.toCharArray(output,sHTMLLevelValue1.length()+1);

//Serial.println(output);
  if (params = e.serviceRequest())
  {
    e.print(F("<!DOCTYPE HTML>\r\n"));
    e.print("<html>\r\n");
    e.print("	<head>\r\n");
    e.print("		<title>The Garduino</title>\r\n");
    e.print("	<style>\r\n");
    e.print("		body, input, select, textarea\r\n");
    e.print("		{color: #888;font: 16pt \"Source Sans Pro\", sans-serif; width: 75%; margin:0 auto;}\r\n");
    e.print("		.level{}\r\n");
    e.print("		.level.bad{color: red}\r\n");
    e.print("</style>\r\n");
    e.print("</head>\r\n<body>\r\n");
    e.print( output );    
//    e.print(sensorValue);
    
    if (strcmp(params, "?cmd=on") == 0)
    {
      digitalWrite(outputPin, HIGH);
      e.print("actually watering: <A HREF='?cmd=off'>stop watering</A>");
    }
    else if (strcmp(params, "?cmd=off") == 0) // Modified -- 2011 12 15 # Ben Schueler
    {
      digitalWrite(outputPin, LOW);
      e.print(" <A HREF='?cmd=on'>start watering</A>");
    }
    e.print("	</body>\r\n");
    e.print("</html>\r\n");
    e.respond();
  }
}

compiler:
Webserver.ino: In function 'void loop()':
Webserver.ino:47: error: invalid conversion from 'const __FlashStringHelper*' to 'int'
Webserver.ino:47: error: initializing argument 1 of 'void ETHER_28J60::print(int)'

As you suspected, the problem in line 47 is caused by e.print() not being able to access data in flash memory. However, it's interesting that the next 10 lines, as well as any of the other constant strings, do not use the F() macro.

Since none of the other strings use the F() macro, the easy fix is to simply take the F() macro off of line 47. In the grand scheme of things the difference in the amount of memory used will be minimal.

Now, if you took the F() macro off the other strings for testing, and only added it back to this one line to show the error, the problem becomes how to get e.print() to recognize these flash strings so you can put F() back in all of these other lines?

Become familiar with these two pages:

  • Arduino Reference - PROGMEM
  • <avr/pgmspace.h>: Program Space Utilities
    The issue is that the processor treats the data and program memory spaces differently. Special instructions are required to be able to access data from program memory. Some functions that process strings have special versions that are automatically selected when a F() style string is encountered. e.print() apparently does not have such a version.

If you look at the example at the bottom of the Arduino Reference page linked above, you will see how they are creating an array of strings in program memory space. Then, they have a loop that copies one at a time into a buffer, and then prints the string from that buffer. Of course, Serial.println() has a special version that can access program memory data directly, so it's not an immediately useful example. But the key is the copying into a RAM buffer. A solution for you might be to put all of those strings in a string array like in the buffer, then where you have the series of e.print() calls replace that with a loop that copies one string at a time into a buffer, and then calls e.print with that buffer.