vrijdag 2 mei 2014

Somfy Controller operational

A lot has happened since my previous blog. The Somfy controller is operational and is controlled by the VeraLite!

A summary of what I did:
  • Dry-wired a Somfy Telis 4 remote  
  • Programmed an Arduino Ethernet to control the Somfy remote
  • Added a light sensor (Phidgets 1143) to the Arduino. The light sensor is installed under the glass roof of my conservatory
  • Added a temperature sensor to the arduino (DS18B20)
  • Added logic to the Arduino to calculate a moving average (1 hour) of the light level and sun percentage 
  • Installed the Arduino test board near its final location
  • Installed wires from the Arduino to 
    • the temperature sensor in the bedroom
    • the lightsensor in the conservatory 
    • the future window sensors in the bedroom 
  • Wrote a Vera plugin that 
    • can operate in manual or automatic mode
    • allows control of 4 Somfy devices (up/down/stop)
    • shows the light level of the light sensor
    • shows the temperature of the temperature sensor
  • Wrote a logger on one of my virtual Linux servers to capture sensor readings every 5 mins and an Excel spreadsheet to show some graphs.

I uploaded the latest Arduino code and Vera plugin here

I'm still working on the automatic control, but already added the control of one of the blinds (roof of conservatory). The logger really helped in determining the values for automatic control. When the average light level is higher than 25000, I close the blind and when it drops below 10000 I open it.

See samples below. The graphs for "Tuin_Temp" (outside garden temperature) and "Serre_Temp" (temperature conservatory) are not measured by Arduino, but Zwave devices (4-1 multisensor).

Cloudy day


Sunny day

Mixed Sun/Clouds





zaterdag 5 april 2014

Full control of Somfy remote via browser

I have built a test setup that can fully control the Somfy Telis 4 remote from a web browser. The complete circuit to control the remote is built onto a breadboard.





  • The four ORANGE wires connect the LEDs of the remote to the analog input pins
  • The GREEN wire supplies 3.3v to the remote (I removed the battery from the remote)
  • The wired buttons of the remote are connected to an optocoupler and GND (YELLOW wires)
  • The optocouplers are connected to the digital (output) pins (BROWN wires)  via a 330 Ohm resistor and GND (BLUE wires)
  • The remote is also wired to GND (WHITE wire)

So how does it work?

The Arduino is acting as a simple webserver listening to incoming requests on port 80. I have defined simple commands to interact with the remote. The Arduino code is available here.

http://<ip address Arduino>/c<channel><button>

where
  • <channel> = 1..5
  • <button> = "u" (up), "s" (stop/my), "d" (down)

example: the URL below will select channel 3 first and then press the 'down' button:

http://<ip address Arduino>/c3d


zondag 30 maart 2014

The Channel selection code

Introduction


Coding the channel selection for the Arduino is not really difficult, but has some attention points.

When the Telis 4 remote is idle and no LEDs are blinking, changing the channel can be established with only two steps:

  1. press the select button to have the remote show its current channel
  2. keep pressing the select button until the right channel is selected
But, we should be able to handle the fact that the LEDs are already be blinking when starting a channel selection, so the steps I implemented are:

  1. look at the LEDs and determine the current selected channel
  2. keep pressing the select button until the right channel is selected
With only a few Arduino functions this can be achieved:

Pressing a button


The buttons of the remote are wired to the Digital Out pins 2-5 of the Arduino. Putting a HIGH signal (+5v) on the pin during 100ms will activate the button. I came up with the 100ms by trial and error (50ms will not trigger the button). 

The Arduino code:

#define SOMFY_BUTTON_UP   2
#define SOMFY_BUTTON_DOWN 3
#define SOMFY_BUTTON_MY   4
#define SOMFY_BUTTON_MENU 5

int press_button(int button){

  
  digitalWrite(button, HIGH);
  delay(100);
  digitalWrite(button, LOW);
}


Reading the status of the LEDs


The LEDs of the remote are wired to the Analog input pins 0-3 of the Arduino. If a LED is off, there will be 3.3V on the pin and when a LED is on around 2V. The analog input pins can be used as digital input pins. They return '0' when the input voltage is 0-2.5V and '1' when the input voltage is 2.5-5V. So for the LEDs on the remote: a '0' means LED is on and a '1' means LED is off.

A point of attention here is that the Arduino reads the digital inputs with a speed of less than 1ms. Because the LEDs are blinking with a speed which is much higher than 1ms, a single read action is not enough. With some test code I found out that the LEDs are on for about 70ms and off for 70ms while blinking. I have chosen to read the input pins every 10ms during 100ms to make sure I capture that the LEDs are on.

The Arduino code:

int get_channel(){

  int sel_channel=0;  // the current channel
  int iLED1=1;        // status LED1: 1=OFF, 0=ON
  int iLED2=1;        // status LED2: 1=OFF, 0=ON
  int iLED3=1;        // status LED3: 1=OFF, 0=ON
  int iLED4=1;        // status LED4: 1=OFF, 0=ON
  int iLEDs;          // status LED1-4 in a byte

  // read the LEDs from the remote and determine the current channel
  // make sure we detect a blinking LED, they go on and off for about 70ms
  // the body of the loop takes <1ms, so check every 10ms during 100ms 
  // to capture a full cycle

  for (int i=0; i<10; i++){
    iLED1 &= digitalRead(SOMFY_LED1_APIN);
    iLED2 &= digitalRead(SOMFY_LED2_APIN);
    iLED3 &= digitalRead(SOMFY_LED3_APIN);
    iLED4 &= digitalRead(SOMFY_LED4_APIN);
    delay(10);
  }

  iLEDs = iLED4<<3 | iLED3<<2 | iLED2<<1 | iLED1;
  switch(iLEDs){
    case 14: sel_channel=1; break; // LED1, channel 1 selected
    case 13: sel_channel=2; break; // LED2, channel 2 selected
    case 11: sel_channel=3; break; // LED3, channel 3 selected
    case 7:  sel_channel=4; break; // LED4, channel 4 selected
    case 0:  sel_channel=5; break; // ALL,  channel 5 selected
   
    default:  sel_channel=0;       // no LEDs are blinking
  }

  return sel_channel;
}

Switching the Channels


The select_channel function will switch the remote to a specified channel 'ch'. It works when the LEDs on the remote are not on, but also when the LEDs are already blinking. First, the current channel is fetched. As long as it is not yet equal to channel 'ch', the select button is pressed. The check with 'prev' is needed, because the time between press_button and get_channel could be too short. The remote will not yet have moved to the next channel, so we read the same channel again and press the button again and move 1 channel too far.

todo:
  • if the get_channel function returns '0' (not sure this might happen): do not press the button, but loop again, eventually we have to detect a channel
  • if for some reason, we will never detect a channel due to a malfunction, the loop must be aborted after a while

int select_channel(int ch){

  int curr; // current channel
  int prev; // previous channel

  // while the current channel is not equal to channel 'ch' go to the next
  // channel by pressing the channel select button
  // the button is only pressed when the previous channel selection changed

  // make sure we press the button the first time, channel is never -1
  prev=-1; 
  while((curr=get_channel())!=ch){
    if (curr!=prev){
      press_button(SOMFY_BUTTON_MENU);
      prev=curr;
    }
  }
}

zondag 23 maart 2014

Wiring the Somfy Telis 4

The Somfy Telis 4 remote has 4 buttons (not inclusing the reset button on the back) and 4 LEDs to indicate the channel.

The buttons

Each button is wired to GND with the two pins on the left side of the button. When the button is pressed, the two pins on the right also get GND. To operate the buttons without physically pressing them: just wire the GND to one of the two pins on the right side of the button. We need to solder 5 wires to the board to have the Arduino control the remote (in the diagram: GND, UP, STOP, DOWN, SELECT)

The LEDs

Each LED is wired to +3V and to the circuit on the board. To let the Arduino know which channel is selected, we are going to measure the voltage between GND and the points marked with LED x. When the LED is not blinking it will read +3V, but when the LED is blinking it will drop to about 1.39V and the LED takes 1.91V.
We need to solder 5 wires to the board (in the diagram: +3V, LED1, LED2, LED3, LED4).

Wiring

I took an old IDE computer cable that I had lying around for the wiring. I removed the battery from the remote, because it will be powered from the +3.3V output on the Arduino. See the final result below.





woensdag 19 maart 2014

The Arduino arrived!

Today I received the Arduino Ethernet, the Arduino Proto shield, the USB to serial device, and the Temperature sensor.


Running your first program is very easy:

  1. Install the Arduino IDE software on your computer (I used the latest windows version 1.0.5-r2)
  2. Plug the USB to serial device into the Arduino and connect the other end of the USB cable to the computer.

  3. After the USB driver was installed, I had to unplug the Arduino and plug it in once again to get it to work.

  4. Launch the Arduino IDE
  5. In the menu, select Tools | Board | Arduino Uno
  6. In the menu, select Tools | Serial Port | <the right COM port>
  7. Open an example program, I took "C:\Program Files (x86)\Arduino\examples\01.Basics\Blink\Blink.ino"
  8. Click the Upload button to compile the program, transfer it to the Arduino, and start it.
  9. Nothing happened in my case, because the Arduino Ethernet does not have an onboard LED on pin 13.
  10. I added some debug statements to the original example program that sends some text back to the IDE using the USB connection to verify its execution (highlighted in blue)

  11. #include <SoftwareSerial.h>

    /*
      Blink
      Turns on an LED on for one second, then off for one second, repeatedly.
      This example code is in the public domain.
     */
    // Pin 13 has an LED connected on most Arduino boards.
    // give it a name:
    int led = 13;

    // the setup routine runs once when you press reset:
    void setup() {                
      // initialize the digital pin as an output.
      pinMode(led, OUTPUT);    
      Serial.begin(9600);           // set up Serial library at 9600 bps 
      Serial.println("Hello world!");
    }

    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      Serial.println("LED on");
      
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      Serial.println("LED off");
      
      delay(1000);               // wait for a second
    }





  12. In the IDE select "Tools | Serial Monitor" to start monitoring your application






  13. Having the LED blink was more fun, so I got the electronics kit I had lying around and hooked up a LED and a resistor to pin 13 and GND.

zondag 16 maart 2014

The plan

The high level plan to build the Somfy controller is as follows:
  • hard wire a Somfy Telis 4 remote to a micro controller to control the Somfy devices
  • use an Arduino Ethernet micro controller
  • program the Arduino to read the sensor values, control the Telis-4 remote, and implements a webserver to communicate with the Vera Lite
  • build a custom plugin for the Vera Lite to communicate with the Arduino
  • connect a temperature controller and a light sensor to the Arduino

Shopping list:
  • Somfy Telis 4 remote
  • Arduino Ethernet microcontroller
  • X FTDI break-out to program the Arduino
  • Arduino proto shield to solder the final circuit
  • X Enclosure for the Arduino and one shield
  • V 4x optocouplers (CNY17-3) to wire the buttons on the Telis 4 to  Arduino
  • V 4x 330 ohm resisters to wire the optocouplers to the digital out pins of  Arduino
  • X 1x digital temperature sensor DS18B20
  • V 1x 4700 ohm pull-up resistor for connecting the DS18B20 to Arduino
  • V 1x analog light sensor APDS-9007 (3-70K lux)
  • V 1x 56K ohm pull-up resistor for connecting the DS18B20 to Arduino

And some other electronics equipment, because this is my first project:
  • V Breadboard and 
  • V cabling to experiment with the setup
  • V a red LED (2.25V, 20mA)
  • V 1x 150 ohm resistor for the LED
  • V a multimeter

V= CONRAD
X= ANTRATEK

Requirements


  • The Somfy controller (SC) needs to be able to communicate via Ethernet with the Vera. I want to position the SC close to the part of the house where the shades are, to limit the cabling to the sensors. A network cable and power outlets are already present on that location.
  • The automatic control should not cause the shades to go up/down too often.
  • The shades should be opened automatically in the evening after sunset.
  • One vertical shade is mounted on the first floor facing the South and covers all windows from the outside.  Main purpose of this shade is to limit the temperature of the rooms there. 
    • Two windows there can be opened and prevent lowering the shade and detection is needed wether the windows are opened/closed. 
    • Another window and a door can also prevent lowering the shade, but they are always closed and only opened for maintenance. An override must be available to block automatic control in case of maintenance.
    • The shade should be lowered when the sun starts heating the rooms.
  • Another vertical blind is mounted on the outside of the kitchen window also facing the South. Two purposes here: limit the temperature in the room, but also to prevent direct sunlight into the kitchen.
    • One window there can be opened and prevent lowering the shade, but this windows is always closed and only opened for maintenance. An override must be available to block automatic control in case of maintenance.
  • A horizontal blind is mounted in a sun room at the back of the house. Two purposes here: limit the temperature in the sun room, but also to prevent direct sunlight into the house.
  • The values of the sun light / temperature readings and also the control of the shades should be logged to be able to analyse and fine tune the automatic control.