Application domotique avec Arduino et CPL

Le but de ce projet et de pouvoir commander certains équipements depuis un site web hébergé sur un raspberry pi (je l’attends toujours…) qui communique avec un arduino relié à une passerelle CPL. Les ordres sont transmis aux différents équipements au travers du CPL en utilisant le protocole X10.

Je vous conseille vivement de lire le document de Patrick Abati qui présente le protocole X10 (le meilleur que j’ai pu trouver pour comprendre le fonctionnement) disponible ICI ou x10 presentation.

Les différents modules présents sur le réseau électrique sont :

J’utilise une librairie déjà existante qui peut être téléchargé ici pour dialoguer avec la passerelle X10 de marmitek : https://code.google.com/p/arduino-x10/

La communication se fait également avec une liaison Xbee avec une carte mère (la même que cette utilise dans l’article sur la station météo). De plus je vais ajouter une liaison USB dès que j’aurai reçu mon Arduino Leonardo (avec une vrai gestion USB et non une liaison série émulé). Cette liaison USB servira a communique avec un Raspberry Pi pour commander les équipements depuis un site Web (en plus de la carte mère).

Voilà le programme complet:

//Xbee library
#include <XBee.h>
//X10
#include <X10ex.h>

#define POWER_LINE_MSG "PL:"
#define POWER_LINE_BUFFER_ERROR "PL:_ExBuffer"
#define SERIAL_DATA_MSG "SD:"
#define SERIAL_DATA_THRESHOLD 1000
#define SERIAL_DATA_TIMEOUT "SD:_ExTimOut"
#define MODULE_STATE_MSG "MS:"
#define MSG_DATA_ERROR "_ExSyntax"
//Next

XBee _Xbee = XBee(); // create Xbee object to control a Xbee
ZBRxResponse _ZbRxResp = ZBRxResponse(); //Create reusable response objects for responses we expect to handle
int _ServoPosition = 90;

//Define the pin number
const int _OutPinLedTest = 8;

// Fields used for serial and byte message reception
unsigned long sdReceived;
char bmHouse;
byte bmUnit;
byte bmCommand;
byte bmExtCommand;
int _CmdReceived = 0;

// X10 Power Line Communication Library
X10ex x10ex = X10ex(
  2, // Zero Cross Interrupt Number (2 = "Custom" Pin Change Interrupt)
  4, // Zero Cross Interrupt Pin (Pin 4-7 can be used with interrupt 2)
  5, // Power Line Transmit Pin 
  6, // Power Line Receive Pin
  true, // Enable this to see echo of what is transmitted on the power line
  powerLineEvent, // Event triggered when power line message is received
  1, // Number of phases (1 = No Phase Repeat/Coupling)
  50 // The power line AC frequency (e.g. 50Hz in Europe, 60Hz in North America)
);

void setup()
{
  //defined input button
  pinMode(_OutPinLedTest,OUTPUT);

  // start serial
  _Xbee.begin(9600);
    // Remember to set baud rate in Serial Monitor or lower this to 9600 (default value)
  Serial.begin(9600);
  // Start the Power Line Communication library
  x10ex.begin();
}

void flashPin(int pin, int times, int wait) 
{
  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);

    if (i + 1 < times) {
      delay(wait);
    }
  }
}

void loop()
{
  _Xbee.readPacket();
  //Reset command to 0
  _CmdReceived = 0;

  if (_Xbee.getResponse().isAvailable()) {
    // got something
    Serial.println("We have something on the serial");
    Serial.print("ApiId: 0x");
    Serial.println(_Xbee.getResponse().getApiId(), HEX);

    if (_Xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
      Serial.println("This is a ZB response");

      // now fill our zb rx class
      _Xbee.getResponse().getZBRxResponse(_ZbRxResp);
      flashPin(_OutPinLedTest, 3, 200);
      _CmdReceived = _ZbRxResp.getData(0);

    }  
  } 
  //Process the command
  //Test if we have an action to do 
  if(_CmdReceived==5)
  {
    x10ex.sendCmd('A', 4, CMD_ON, 1);
  }
  else if(_CmdReceived==6)
  {
    x10ex.sendCmd('A', 4, CMD_OFF, 1);
  }
  else if(_CmdReceived==7)
  {
    x10ex.sendCmd('A', 5, CMD_ON, 1);
  }
  else if(_CmdReceived==8)
  {
    x10ex.sendCmd('A', 5, CMD_OFF, 1);
  }
  else if(_CmdReceived==9)
  {
    x10ex.sendCmd('A', 7, CMD_ON, 1);
  }
  else if(_CmdReceived==10)
  {
    x10ex.sendCmd('A', 7, CMD_OFF, 1);
  }
  else if(_CmdReceived==11)
  {
    x10ex.sendCmd('A', 7, CMD_ON, 1);
    x10ex.sendCmd('A', 5, CMD_ON, 1);
  }
  else if(_CmdReceived==12)
  {
    x10ex.sendCmd('A', 7, CMD_OFF, 1);
    x10ex.sendCmd('A', 5, CMD_OFF, 1);
  }
}

void printX10Message(const char type[], char house, byte unit, byte command, byte extData, byte extCommand, int remainingBits)
{
  printX10TypeHouseUnit(type, house, unit, command);
  // Ignore non X10 commands like the CMD_ADDRESS command used by the IR library
  if(command <= 0xF)
  {
    Serial.print(command, HEX);
    if(extCommand || (extData && (command == CMD_STATUS_ON || command == CMD_STATUS_OFF)))
    {
      printX10ByteAsHex(extCommand);
      printX10ByteAsHex(extCommand == EXC_PRE_SET_DIM ? extData & B111111 : extData);
    }
  }
  else
  {
    Serial.print("_");
  }
  Serial.println();
}

void printX10TypeHouseUnit(const char type[], char house, byte unit, byte command)
{
  Serial.print(type);
  Serial.print(house);
  if(
    unit &&
    unit != DATA_UNKNOWN/* &&
    command != CMD_ALL_UNITS_OFF &&
    command != CMD_ALL_LIGHTS_ON &&
    command != CMD_ALL_LIGHTS_OFF &&
    command != CMD_HAIL_REQUEST*/)
  {
    Serial.print(unit - 1, HEX);
  }
  else
  {
    Serial.print("_");
  }
}

void printX10ByteAsHex(byte data)
{
  Serial.print("x");
  if(data <= 0xF) { Serial.print("0"); }
  Serial.print(data, HEX);
}

byte charHexToDecimal(byte input)
{
  // 0123456789  =>  0-15
  if(input >= 0x30 && input <= 0x39) input -= 0x30;
  // ABCDEF  =>  10-15
  else if(input >= 0x41 && input <= 0x46) input -= 0x37;
  // Return converted byte
  return input;
}

// Process messages received from X10 modules over the power line
void powerLineEvent(char house, byte unit, byte command, byte extData, byte extCommand, byte remainingBits)
{
  printX10Message(POWER_LINE_MSG, house, unit, command, extData, extCommand, remainingBits);
}

 

2 thoughts on “Application domotique avec Arduino et CPL

  1. Pingback: Migration Arduino Uno vers Arduino Leonardo | Djynet

  2. Pingback: Merge ! | Djynet

Comments are closed.