X10 / Arduino

From Hackerspace ACKspace
Revision as of 14:24, 23 May 2017 by Xopr (talk | contribs) (project stalled (probably))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Project: X10 / Arduino
Featured: No
State Stalled
Members Eagle00789
GitHub No GitHub project defined. Add your project here.
Description Let Arduino control my X10 Controllers
Picture
X10-1.jpg

Make Arduino control any X10 appliance in a single home. It would be the most fun to make the arduino available via a web-interface and control the X10 appliances via the webinterface using the arduino

Hardware

De benodigde hardware hiervoor is inmiddels binnen. De hardware bestaat uit:

  • Arduino Mega 2560 ([[1]])
  • Arduino Mega Proto Shield ([[2]])
  • LCD Shield van SparkFun ([[3]])
  • Ethernet Shield van sparkfun ([[4]])
  • XM10 TTL/CMOS interface ([[5]])
  • RF Receiver - 434MHz ([6])
  • DS1307 RTC van Sparkfun ([[7]])

Huidige status

Het ethernetshield werkt zonder problemen. Het lcd shield heeft echter problemen met de library. Hierdoor ben ik nu al veel tijd kwijt met het omprogrammeren van deze library. Deze library werkt inmiddels zonder problemen verder. De DS1307 werkt naar behoren. Het Ethernet shield wordt nu alleen gebruikt als NTP client. Op het LCD shield is inmiddels een compleet werkend menu te vinden. De X10 interface werkt inmiddels ook zonder problemen.

Toekomstige acties

De NTP gegevens worden straks alleen gebruikt om de RTC te updaten. Mogelijkheid tot het presenteren van een webpagina waarop de X10 modules kunnen worden afgelezen en bestuurd. De RF receiver moet nog getuned worden en aangesloten worden. Ook moeten de ontvangen signalen nog worden omgezet naar X10.

Foto's

Hieronder een paar foto's van de apparatuur die tot nu toe gebruikt wordt voor dit project.

BRONCODE

Hieronder de volledige broncode van de X10 controller in zijn huidige staat:

#include <Time.h>
#include <x10.h>
#include <x10constants.h>
#include "LCD_driver.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <SPI.h>         
#include <Ethernet.h>
#include <Udp.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//byte ip[] = { 192,168,0,177 }; //thuis
//byte gw[] = { 192,168,0,1}; //thuis
byte ip[] = { 10,0,30,177 }; //ACKspace
byte gw[] = { 10,0,30,254}; //ACKspace
byte netmask[] = { 255,255,255,0 };

byte timeServer[] = { 
  85, 12, 35, 12}; // nl.pool.ntp.org NTP server

unsigned int localPort = 8888;      // local port to listen for UDP packets

const int NTP_PACKET_SIZE= 48;

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

char *strHour;
char *strMin;
char *strSec;

#define MENUITEMS 5
#define MAXSUBMENUITEMS 8

int activeMenu;
int activeSubMenu;
int activeMenuType;
char *menu[MENUITEMS][MAXSUBMENUITEMS];

#define zcPin 24
#define rxPin 25
#define txPin 28
#define HOUSE HOUSE_D
#define BRIGHTLEVEL0   0
#define BRIGHTLEVEL25  3
#define BRIGHTLEVEL50  6
#define BRIGHTLEVEL75  8
#define BRIGHTLEVEL100 11

x10 myHouse =  x10(zcPin, txPin, rxPin);

void	setup()
{
  //Serial.begin(9600);
  activeMenu = 0;
  activeSubMenu = 1;
  activeMenuType = 0;
  LCDInit();	    //Initialize the LCD
  LCDContrast(44);
  menu[0][0] = "Enable module";
  menu[0][1] = "TV Light";
  menu[0][2] = "Wall Light";
  menu[0][3] = "Standing Light";
  menu[0][4] = "Cabinet Light";
  menu[0][5] = "Bedroom Light";
  menu[0][6] = "Stable Light";
  menu[0][7] = "<< Back >>";
  menu[1][0] = "Disable module";
  menu[1][1] = "TV Light";
  menu[1][2] = "Wall Light";
  menu[1][3] = "Standing Light";
  menu[1][4] = "Cabinet Light";
  menu[1][5] = "Bedroom Light";
  menu[1][6] = "Stable Light";
  menu[1][7] = "<< Back >>";
  menu[2][0] = "Control shutters";
  menu[2][1] = "Block sun";
  menu[2][2] = "100%";
  menu[2][3] = " 75%";
  menu[2][4] = " 50%";
  menu[2][5] = " 25%";
  menu[2][6] = "  0%";
  menu[2][7] = "<<  Back >>";
  menu[3][0] = "All modules on";
  menu[4][0] = "All modules off";
  PrintMenu(0);
  Ethernet.begin(mac,ip,gw,netmask);
  Udp.begin(localPort);
  setSyncProvider(UpdateTime);
//  RTC.stop();
//  RTC.set(DS1307_SEC,30);        //set the seconds
//  RTC.set(DS1307_MIN,6);     //set the minutes
//  RTC.set(DS1307_HR,16);       //set the hours
//  RTC.set(DS1307_DOW,3);       //set the day of the week
//  RTC.set(DS1307_DATE,5);       //set the date
//  RTC.set(DS1307_MTH,10);        //set the month
//  RTC.set(DS1307_YR,11);         //set the year
//  RTC.start();
}

void	loop()
{
  char CurrentTime[8];
  sprintf(CurrentTime, "%02d:%02d:%02d",RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false),RTC.get(DS1307_SEC,false));
  LCDPutStr(CurrentTime, 0, 63, GREEN, WHITE);
  MenuButtons();
  if(timeStatus() == timeSet)
  {
    UpdateTimeDisplay();
  }
}

void UpdateTimeDisplay()
{
  char CurrentTime[8];
  int DSTAdjust;
  if (month() < 3 || month() > 11)
  {
    DSTAdjust = 0;
  }
  if (month() > 3 && month() < 11)
  {
    DSTAdjust = 1;
    int previousSunday = day() - weekday();
    if (month() == 3 && previousSunday >= 8)
    {
      DSTAdjust = 1;
    }
    if (month() == 10 && previousSunday <= 0)
    {
      DSTAdjust = 0;
    }
  }
  sprintf(CurrentTime, "%02d:%02d:%02d",hour()+DSTAdjust+1,minute(),second());
  if (activeMenuType == 0)
  {
    LCDPutStr(CurrentTime, 0, 63, GREEN, WHITE);
  }
}

unsigned long UpdateTime()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server
  delay(1000);
  if ( Udp.available() ) {  
    Udp.readPacket(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    unsigned long secsSince1900 = highWord << 16 | lowWord;  
    const unsigned long seventyYears = 2208988800UL;     
    unsigned long epoch = secsSince1900 - seventyYears;  
    return epoch;
  }
  return 0;
}

unsigned long sendNTPpacket(byte *address)
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE,  address, 123); //NTP requests are to port 123
}

void   MenuButtons()
{
  int	s1, s2, s3;
  s1	=	!digitalRead(kSwitch1_PIN);
  s2	=	!digitalRead(kSwitch2_PIN);
  s3	=	!digitalRead(kSwitch3_PIN);

  if (s1)
  {
    ButtonDown();
  }
  else if (s2)
  {
    ButtonSelect();
  }
  else if (s3)
  {
    ButtonUp();
  }
  s1 = 0;
  s2 = 0;
  s3 = 0;
  delay(150);
}

void   ButtonUp()
{
  if (activeMenuType == 0)
  {
    int tmpMenuPos = (activeMenu * 16) + 16;
    PrintMenuItem(menu[activeMenu][0], 0, tmpMenuPos);
    activeMenu--;
    if (activeMenu < 0)
    {
      activeMenu = MENUITEMS - 1;
    }
    tmpMenuPos = (activeMenu * 16) + 16;
    PrintMenuItem(menu[activeMenu][0], 1, tmpMenuPos);
  }
  else
  {
    int tmpMenuPos = ((activeSubMenu - 1) * 16) + 16;
    PrintMenuItem(menu[activeMenu][activeSubMenu], 0, tmpMenuPos);
    activeSubMenu--;
    if (activeSubMenu < 1)
    {
      activeSubMenu = MAXSUBMENUITEMS - 1;
    }
    tmpMenuPos = ((activeSubMenu - 1) * 16) + 16;
    PrintMenuItem(menu[activeMenu][activeSubMenu], 1, tmpMenuPos);
  }
}

void   ButtonSelect()
{
  switch (activeMenu)
  {
    case 0:
      if (activeMenuType == 0)
      {
        activeMenuType = 1;
        PrintSubMenu(activeMenu);
        break;
      }
      else
      {
        switch (activeSubMenu)
        {
          case 1:
            TurnLightOn(UNIT_9);
            break;
          case 2:
            TurnLightOn(UNIT_10);
            break;
          case 3:
            TurnLightOn(UNIT_11);
            break;
          case 4:
            TurnLightOn(UNIT_12);
            break;
          case 5:
            TurnLightOn(UNIT_13);
            break;
          case 6:
            TurnLightOn(UNIT_5);
            break;
          case 7:
            activeMenuType = 0;
            PrintMenu(0);
            break;
        }
      }
      break;
    case 1:
      if (activeMenuType == 0)
      {
        activeMenuType = 1;
        PrintSubMenu(activeMenu);
        break;
      }
      else
      {
        switch (activeSubMenu)
        {
          case 1:
            TurnLightOff(UNIT_9);
            break;
          case 2:
            TurnLightOff(UNIT_10);
            break;
          case 3:
            TurnLightOff(UNIT_11);
            break;
          case 4:
            TurnLightOff(UNIT_12);
            break;
          case 5:
            TurnLightOff(UNIT_13);
            break;
          case 6:
            TurnLightOff(UNIT_5);
            break;
          case 7:
            activeMenuType = 0;
            PrintMenu(1);
            break;
        }
      }
      break;
    case 2:
      if (activeMenuType == 0)
      {
        activeMenuType = 1;
        PrintSubMenu(activeMenu);
        break;
      }
      else
      {
        switch (activeSubMenu)
        {
          case 1:
            SetLightLevel(UNIT_14, BRIGHTLEVEL25);
            break;
          case 2:
            SetLightLevel(UNIT_14, BRIGHTLEVEL100);
            break;
          case 3:
            SetLightLevel(UNIT_14, BRIGHTLEVEL75);
            break;
          case 4:
            SetLightLevel(UNIT_14, BRIGHTLEVEL50);
            break;
          case 5:
            SetLightLevel(UNIT_14, BRIGHTLEVEL25);
            break;
          case 6:
            //SetLightLevel(UNIT_14, BRIGHTLEVEL0);
            TurnLightOff(UNIT_14);
            break;
          case 7:
            activeMenuType = 0;
            PrintMenu(2);
            break;
        }
      }
      break;
    case 3:
      TurnLightOn(UNIT_9);
      TurnLightOn(UNIT_10);
      TurnLightOn(UNIT_11);
      TurnLightOn(UNIT_12);
      break;
    case 4:
      TurnLightOff(UNIT_9);
      TurnLightOff(UNIT_10);
      TurnLightOff(UNIT_11);
      delay(150000);
      TurnLightOff(UNIT_12);
      break;
  }
}

void   ButtonDown()
{
  if (activeMenuType == 0)
  {
    int tmpMenuPos = (activeMenu * 16) + 16;
    PrintMenuItem(menu[activeMenu][0], 0, tmpMenuPos);
    activeMenu++;
    if (activeMenu >= MENUITEMS)
    {
      activeMenu = 0;
    }
    tmpMenuPos = (activeMenu * 16) + 16;
    PrintMenuItem(menu[activeMenu][0], 1, tmpMenuPos);
  }
  else
  {
    int tmpMenuPos = ((activeSubMenu - 1) * 16) + 16;
    PrintMenuItem(menu[activeMenu][activeSubMenu], 0, tmpMenuPos);
    activeSubMenu++;
    if (activeSubMenu >= MAXSUBMENUITEMS)
    {
      activeSubMenu = 1;
    }
    tmpMenuPos = ((activeSubMenu - 1) * 16) + 16;
    PrintMenuItem(menu[activeMenu][activeSubMenu], 1, tmpMenuPos);
  }
}

void   TurnLightOn(int Unit)
{
  myHouse.write(HOUSE, Unit, 1);
  myHouse.write(HOUSE, ON, 1);
}

void   TurnLightOff(int Unit)
{
  myHouse.write(HOUSE, Unit, 1);
  myHouse.write(HOUSE, OFF, 1);
}

void   SwitchLight(int Unit)
{
  //
}

void   SetLightLevel(int Unit, int Level)
{
  myHouse.write(HOUSE, Unit, 1);
  myHouse.write(HOUSE, BRIGHT, 1);
}

void   PrintMenu(int ActiveMainMenu)
{
  LCDClear(WHITE);
  PrintMenuTitle("MENU");
  int row, col, line;
  line = 16;
  for (row = 0; row < MENUITEMS; row++)
  {
    if (row == ActiveMainMenu)
    {
      PrintMenuItem(menu[row][0], 1, line);
    }
    else
    {
      PrintMenuItem(menu[row][0], 0, line);
    }
    line += 16;
  }
}

void   PrintSubMenu(int ActiveMainMenu)
{
  activeSubMenu = 1;
  LCDClear(WHITE);
  PrintMenuTitle(menu[ActiveMainMenu][0]);
  int row, col, line;
  line = 16;
  for (row = 1; row < MAXSUBMENUITEMS; row++)
  {
    if (row == 1)
    {
      PrintMenuItem(menu[ActiveMainMenu][row], 1, line);
    }
    else
    {
      PrintMenuItem(menu[ActiveMainMenu][row], 0, line);
    }
    line += 16;
  }
}

void   PrintMenuTitle(char *menuString)
{
  LCDPutStr(menuString, 0, 0, RED, WHITE);
}

void  PrintMenuItem(char *menuString, int Active, int x)
{
  if (Active == 1)
  {
    LCDPutStr(menuString, x, 1, BLUE, WHITE);
  }
  else
  {
    LCDPutStr(menuString, x, 1, BLACK, WHITE);
  }
}