Arduino uno with ethernet shield with openhab


#1

Hi,
I am trying to get the arduino uno with ethernet shield ( https://goo.gl/images/SQpbMZ ) to connect to openhab or homeassitant to work as an ESP8266 module (or Sonoff).
I didn’t had any luck. can you guys give me an example schetch that i can use?

Best regards,
Synco


#2

I have used the EtherTen module with OpenHAB. You need a sketch with the Ethernet library and I am also using an MQTT library. I can post the code later. My implementation also has the FastLED library.
MQTT does most the work of talking to the server.

What setup are you using?


#3

Hi Synco,

Here is my complete sketch. As noted, it uses multiple libraries so may be a little more involved than what you’re looking for. I separated sections with forward slashes - ///////////

This runs two LED strips, has a capacitive touch sensor as a button, analog light sensor, and talks over ethernet to an MQTT server. This is running on a Freetronics EtherTen module which is crammed for additional code space.

The EtherTen if you aren’t familiar is basically an Uno + Ethernet shield all in one. I am powering the system from the Freetronics Midspan injector to run power and ethernet all in one cable.

Here is a quick video of the system:

#include <FastLED.h>

/// ethernet setup
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 99);
IPAddress server(192, 168, 1, 1);

EthernetClient ethClient;
PubSubClient client(ethClient);

#define DATA_PIN    A0
#define DATA_PIN_2    A1
#define NUM_LEDS    10
#define NUM_LEDS_2   9
#define BRIGHTNESS  128
#define LED_TYPE    TM1803
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define InputPin  7 // switch for turning lights on/off

bool run = false;

//fastled

#define FRAMES_PER_SECOND  120 

// MQTT
unsigned long lastReadTime; //the last time we read the light pin (high-speed read) 
unsigned long lastReportedReadTime; //the last time light level was pushed to MQTT (low speed read+publish)
int prevReadValue; //last read value of the light pin

#define readTimer 100 // interval to read the light pin (high speed read) //was int
#define readTimerMQTT 300000 //interval to read for MQTT publishes (low speed read) // was unsigned long

#define lightPin A4 //analog pin of photocell

void setup() {

  lastReadTime=millis(); // last read for regular readings

  lastReportedReadTime=millis()-readTimerMQTT; //last time a read was published to MQTT
  
  prevReadValue=analogRead(lightPin); //initial reading of photocell
  
  delay( 3000 ); // power-up safety delay (FastLED)

  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.addLeds<LED_TYPE,DATA_PIN_2,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
 
  FastLED.setBrightness(  BRIGHTNESS );

  pinMode(lightPin, INPUT); //light sensor
  pinMode(InputPin, INPUT);

  //currentPalette = RainbowColors_p;
  //currentBlending = LINEARBLEND;


  //ethernet
  client.setServer(server, 1883);
  client.setCallback(callback);

  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);  
}


// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns

  

void loop()
{

  // ethernet
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  
  readAnalog();
  checkInputs();

  if (run) {
    FastLED.setBrightness(BRIGHTNESS);
    
    runFastLED(); // run simulation frame

    FastLED.show();
    //FastLED.delay(1000 / UPDATES_PER_SECOND);
  }
  else{ //turn off the lights
    FastLED.show(0);

  }


}

//////// Code to scan for a physical button press, take action, and report to MQTT

void checkInputs()
{
  
  if(digitalRead(InputPin) == HIGH){
    delay(10); //debounce
    if(digitalRead(InputPin) == HIGH) {
      client.publish("home/kitchen/button1","ON");
      run = !run; //invert
      if(run) client.publish("home/kitchen/stringLights/status", "ON");
      else if(run== false) client.publish("home/kitchen/stringLights/status", "OFF");
      delay(500);
    }
    
  }
}

///////// FastLED related code:
void runFastLED(){

  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

  // send the 'leds' array out to the actual LED strip
  FastLED.show();  
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND); 

  // do some periodic updates
  EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
  EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically  
}


 


#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern()
{
  // add one to the current pattern number, and wrap around at the end
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

void rainbow() 
{
  // FastLED's built-in rainbow generator
  fill_rainbow( leds, NUM_LEDS, gHue, 7);
}

void rainbowWithGlitter() 
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void addGlitter( fract8 chanceOfGlitter) 
{
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

void confetti() 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( gHue + random8(64), 200, 255);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16(13,0,NUM_LEDS);
  leds[pos] += CHSV( gHue, 255, 192);
}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
  }
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16(i+7,0,NUM_LEDS)] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

///////// Code to respond to callbacks (messages) from the MQTT Topics that we're listening to
void callback(char* topic, byte* payload, unsigned int length) {
    payload[length] = '\0'; //set terminator for payload length (or part of old messages could show up)
    
    //Command will be either "ON" or "OFF" 
    String s = String((char*)payload); //convert payload to string

    
    if(strcmp(topic, "home/kitchen/stringLights/command")==0){
    //Note - don't publish a new command before reading in the current one - the library uses the same buffer for send & rec. This will confuse it.
    // https://community.openhab.org/t/rgb-led-strip-control-using-arduino-and-mqtt/4366 
    // https://community.openhab.org/t/oh2-how-to-convert-colorpicker-to-rgb-values/16305/5
    

    if(s == "OFF") {
      run = false;
      client.publish("home/kitchen/stringLights/status", "OFF");
    }

    else if(s == "ON") {
    //if(strcmp( (char *) payload, "ON") == 0) {
      run = true;
      client.publish("home/kitchen/stringLights/status", "ON");
      }
    } //end of the command callback
    
    
    else if(strcmp(topic, "home/kitchen/stringLights/color")==0){    
        if(s == "OFF") {
      run = false;
      client.publish("home/kitchen/stringLights/status", "OFF");
    }

    else if(s == "ON") {
    //if(strcmp( (char *) payload, "ON") == 0) {
      run = true;
      client.publish("home/kitchen/stringLights/status", "ON");
      }
      
//    else if(strcmp(s.substring(0,5), "color")==0){
        // set the color
//      }  
    
    } //end of the color callback
  
}



void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    // Attempt to connect
    if (client.connect("KitchenLightController", "username", "password", "home/kitchen/LWT", 1, 1, "Offline")) {
      client.publish("home/kitchen/LWT","Online");
      client.subscribe("home/kitchen");
      client.subscribe("home/kitchen/stringLights/command");
      client.subscribe("home/kitchen/stringLights/color");
      client.subscribe("home/kitchen/stringLights/brightness");
/* removed to resolve crashing
      //post IP address to MQTT
      String IPCurrent="";
      char str[4];
      for(int n=0; n<4; n++){
        itoa((int)Ethernet.localIP()[n], str, 10);
        IPCurrent +=str;
        if(n<3) IPCurrent +=".";
      }
      IPCurrent.toCharArray(str, 20);
      
      client.publish("home/kitchen/ControllerIPAddress", str);
      
*/
  }
    
    else {
      delay(5000);
    }
  }
}

///// Code to read analog (ambient light) sensor; take action; and report to MQTT

void readAnalog(){
  
  if(millis() >= lastReadTime+readTimer) //see if we need to read the light pin
  {

    
    int lightReadValue=1024-(analogRead(lightPin));

    char lightChar[10] = "";
    dtostrf(lightReadValue, 3,0, lightChar);

    //publish large changes
    if(abs(lightReadValue - prevReadValue) > 5){
      client.publish("home/kitchen/lightLevel", lightChar);
      lastReportedReadTime=millis(); 
    }

    //or just publish every five minutes
    else if(millis() >= lastReportedReadTime+readTimerMQTT){
      client.publish("home/kitchen/lightLevel", lightChar);
      lastReportedReadTime=millis(); 
    }
    
    if(lightReadValue <= 65 && prevReadValue > 65){
      //currentPalette = CloudColors_p;
      FastLED.show();
      delay(5000);
      run=false; //disable FastLED library
    }
    lastReadTime=millis();
    prevReadValue=lightReadValue; //remember previous read
    
  }
  
}

#4

I’m also using EtherTen for one lighting but also generic Ethernet shields on a couple of others, all using the similar sketches which are based off Jonathon’s relay and switch sketches.

One thing that caught me out to start with is that up until last week you needed either Ethernet.h OR ethernet2.h (I think those are the names, this off top of head) library depending on if you have a board with W5100 or W5500. However the Ethernet.h library has now been updated to handle both boards (and others) automatically so make sure you have version 2 and see if makes any difference.

If still no luck, post your sketch and what you are seeing out of serial output. I have a spare one on my desk I can test you code with if you like.