Introduction: Send Sensor Data (DHT11 & BMP180) to ThingSpeak With an Arduino, Using ENC28J60 Ethercard

Picture of Send Sensor Data (DHT11 & BMP180) to ThingSpeak With an Arduino, Using ENC28J60 Ethercard

Note: This instructable is for the old ENC26J60 Ethershield and ethercard. If you have the modern WIZ5100 based Ethernetshield or an ESP8266 go visit my other instructable that I mention below

About a year and a half ago I published an instructable showing how to upload data to Thingspeak with an Arduino W5100 based Ethernet card or an ESP8266. There however is another ethernet card for the Arduino, being the ENC28J60 based Ethercard. It is available as Shield, but also as a module.

Though I wouldnt advise anybody to buy the Ethercard, as the W5100 Ethernetcard is more versatile, many people may still have one and rather than gathering dust one might as well put it to use

Things you need:
ENC28J60 based EtherShield or Ethercard ( or module)
Thingspeak Account
Sensors (DHT11 and BMP180)
Internet connection

Step 1: Send Sensor Data (DHT11 & BMP180) to ThingSpeak With an Arduino, Using ENC28J60 Ethercard: Issues

The libraries

There are basically 4 libraries for the ENC28J60

Ethershield (development stopped) uses pin10 as chipselect
Ethercard develped to allow use of an SD card, uses pin 8 as chipselect
Ether_2860 from Simon Monk. If you do not already have that one, you probably will never get it.

UIPEthernet from Norbert Truchsess. This library is a drop in replacement for the WS5100 Ethernet library, it makes the ENC28J60 behave like a WIZ5100.That means that programs developed for the latter, can be used for the former, simply by replacing

#include <Ethernet.h> by #include <UIPEthernet.h>

However, that does require some memory.

When googling for the ethercard library, one may come across forks of the various libraries as well.

If for whatever reason you want to use the Ethercard library with pin 10 (e.g. if you use it with the Ethershield), change the pin assignment in the library files ENC28J60.h (line 25 and 41 I believe) and the EtherCard.h (Line 134: uint8_t csPin = 8 ). (Depending on the version it can also be in line 154.)

But it is easier to add the declaration for pin 10 in the program itself like this:

ether.begin(sizeof Ethernet::buffer, mymac, 10)

In this instructable I will be using the Ethercard library.

The Ethershield- and Ethercard shield as wel as most of the modules expect 3.3 Volt.

The Thingspeak Data Format
In my earlier instructable on Thingspeak, i discussed the dataformat and particularly that it expects strings, whereas the DHT11 and BMP180 deliver floats.

The program
Fortunately the EtherCard library had a good example to start from. Although Initially I added a routine to convert the float data to strings, I realized that the Ethercard library sends the data to Thingspeak through the print class. Generally this turns floats int strings. tested it and yes, I do not have to do a string conversion and still keep precision in the data.

The ENC28J60 is quite hungry regarding memory so the program has reached a critical mass with only 412 bytes to spare for local variables. I have had it running constantly for 2 days without any problem. I could probably win some memory by stripping the adafruit BMP library a bit,

Step 2: The Code

The program. As instructables is not great in publishing code, I suggest to use the file that i have added

// The full development history of this code is in the attached file

#include <EtherCard.h> // if this library disappeared, it is EtherCard.h
#include <Wire.h> // it is Wire.h
#include <Adafruit_BMP085.h> // it is Adafruit_BMP085.h
#include <dht11.h> // it is dht11.h
#define DHT11PIN 2
Adafruit_BMP085 bmp;
dht11 DHT11;
#define APIKEY "QTRR4654FRE3" // put your key here
#define ethCSpin 10 // put your CS/SS pin here.
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x75,0x68,0x68,0x68,0x68,0x68 };
const char website[] PROGMEM = "";
byte Ethernet::buffer[700];
uint32_t timer;
Stash stash;
byte session;
//timing variable
int res = 100; // was 0

void setup () {
  Serial.println("\n[ThingSpeak example]");

  //Initialize Ethernet

void loop () { 
int chk =;
int t=(DHT11.temperature);
int h=(DHT11.humidity);

            float p=(bmp.readPressure()/100.0);//this is for pressure in hectoPascal
            float m=(bmp.readPressure()/133.3);//  this is for pressure in mmHG
            float t2=(bmp.readTemperature());
  //if correct answer is not received then re-initialize ethernet module
  if (res > 220){
  res = res + 1;
  //200 res = 10 seconds (50ms each res)
  if (res == 200) {

    // field1=(Field 1 Data)&field2=(Field 2 Data)&field3=(Field 3 Data)&field4=(Field 4 Data)&field5=(Field 5 Data)&field6=(Field 6 Data)&field7=(Field 7 Data)&field8=(Field 8 Data)&lat=(Latitude in Decimal Degrees)&long=(Longitude in Decimal Degrees)&elevation=(Elevation in meters)&status=(140 Character Message)
    byte sd = stash.create();

      // generate the header with payload - note that the stash size is used,
    // and that a "stash descriptor" is passed in as argument using "$H"
    Stash::prepare(PSTR("POST /update HTTP/1.0" "\r\n"
      "Host: $F" "\r\n"
      "Connection: close" "\r\n"
      "X-THINGSPEAKAPIKEY: $F" "\r\n"
      "Content-Type: application/x-www-form-urlencoded" "\r\n"
      "Content-Length: $D" "\r\n"
    website, PSTR(APIKEY), stash.size(), sd);

    // send the packet - this also releases all stash buffers once done
    session = ether.tcpSend(); 

 // added from:
 int freeCount = stash.freeCount();
    if (freeCount <= 3) {   Stash::initMap(56); } 
   const char* reply = ether.tcpReply(session);
   if (reply != 0) {
     res = 0;
    // Serial.println(F(" >>>REPLY recieved...."));
    // Serial.println(reply);

void initialize_ethernet(void){  
  for(;;){ // keep trying until you succeed 
    //Reinitialize ethernet module
    //Serial.println("Reseting Ethernet...");
    //digitalWrite(5, LOW);
    //digitalWrite(5, HIGH);

    if (ether.begin(sizeof Ethernet::buffer, mymac, ethCSpin) == 0){ 
      Serial.println( F("Failed to access Ethernet controller"));
    if (!ether.dhcpSetup()){
      Serial.println(F("DHCP failed"));

    ether.printIp("IP:  ", ether.myip);
    ether.printIp("GW:  ", ether.gwip);  
    ether.printIp("DNS: ", ether.dnsip);  

    if (!ether.dnsLookup(website))
      Serial.println(F("DNS failed"));

    ether.printIp("SRV: ", ether.hisip);

    //reset init value
    res = 180;



Pogo28 (author)2017-07-23

Hi, Anyone have tried out HLK RM04 wifi module with ThingSpeak. If you do, Please upload the tutorial. Thanks ahead.

rpurser (author)2016-06-06

Check out the Arduino ThingSpeak library that's pretty memory efficient, and solves the float / string problem:

diy_bloke (author)rpurser2016-06-06

Thanks. I know that library but as far as I know that does not take the ethershield/ethercard into account so it won' t work.

Also, there is not really a float/string problem. As the ethercard library uses a print statement, the float is turned into a string. easypeasy :-)

About This Instructable




Bio: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I ... More »
More by diy_bloke:Working With the Funduino W5100 Ethernet Module.Uploading Data to ThingSpeak With MQTTAdding an MCP23017 I/O Extender to Arduino or ESP8266
Add instructable to: