Pages: [1] 2 3 ... 8   Go Down
Author Topic: Control Livolo switches / Livolo switch library  (Read 43381 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,

I was looking for a way to control Livolo wireless switches. Seller only told me it was a 433.92 MHz thing, but wonderful RC-Switch wouldn't read them. I'm not a programmer, so I had to use the most simple approach. That is record command with Audacity, figure out pattern and pulses length, and hardcode it for Arduino.

In case you have the same switches, feel free to use this code to control them. Hardcoded are 11 buttons (0 to 9 plus All off). As Livolo switches are learning, they should be programmable with this commands. Just put switch into learning mode and transmit command you wish.

================================

IMPORTANT UPDATE
Code below is outdated.

Please see newest code here.

As of 25.10.2013 code avaliable as a library: Livolo switch library.

================================

LIVOLO REMOTE RECEIVER FOR ARDUINO

http://forum.arduino.cc/index.php?topic=153525.msg1560970#msg1560970

Thanks, daleldalel!

LIVOLO REMOTE RECEIVER AND TRANSMITTER FOR RASPBERRY PI

http://forum.arduino.cc/index.php?topic=153525.msg1537781#msg1537781

Thanks, platenspeler!

================================
Code:
int txPin = 9; // pin connected to RF transmitter
int i; // counter to send command pulses
int pulse; // count pulse repetitions
int incomingByte = 0;   // for incoming serial data

// hard coded commands (see txButton): 1 - pulse start, 2 - zero, 3 - one, 4 - pause, 5 - low
int button1[45]={44, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2};
int button2[43]={43, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2};
int button3[41]={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 5, 3, 4, 2, 4, 2, 4, 2};
int button4[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2};
int button5[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2};
int button6[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2, 4, 2};
int button7[41]={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 5, 3, 4, 2, 4, 2};
int button8[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2};
int button9[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2};
int button10[43]={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 2, 4, 3, 4, 2, 4, 2, 4, 2};
int button11[41]={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 5, 2, 4, 3, 4, 2};

void setup () {

pinMode(txPin, OUTPUT);
     Serial.begin(9600);
     Serial.println("Number = button;  a to press 0;  b to shut off all");

}

    void loop(){
      if (Serial.available() > 0) {
        // read the incoming byte:
        incomingByte = Serial.read();
        switch(incomingByte) {
        case 49:
        txButton(button1);
        Serial.println("Switching on 1");
        break;
        case 50:
        txButton(button2);
        Serial.println("Switching on 2");
        break;
        case 51:
        txButton(button3);
        Serial.println("Switching on 3");
        break;
        case 52:
        txButton(button4);
        Serial.println("Switching on 4");
        break;
        case 53:
        txButton(button5);
        Serial.println("Switching on 5");
        break;
        case 54:
        txButton(button6);
        Serial.println("Switching on 6");
        break;
        case 55:
        txButton(button7);
        Serial.println("Switching on 7");
        break;
        case 56:
        txButton(button8);
        Serial.println("Switching on 8");
        break;
        case 57:
        txButton(button9);
        Serial.println("Switching on 9");
        break;
        case 97:
        txButton(button10);
        Serial.println("Switching on 0");
        break;
        case 98:
        txButton(button11);
        Serial.println("Switching All off");
        break;
        }
      } // end if serial available
    }// end void loop
   
// transmit command. Due to transmitter (or something, I don't know) transmission code should be INVERTED. Ex: one is coded as LOW-delay->HIGH instead of HIGH-delay-LOW
void txButton(int cmd[]) {
Serial.print("Processing. Array size is ");
Serial.println(cmd[0]);
digitalWrite(txPin, HIGH); // not sure if its required, just an attempt to start transmission to enable AGC of the receiver
delay(1000);

for (pulse= 0; pulse <= 100; pulse=pulse+1) { // repeat command 100 times
for (i = 1; i < cmd[0]+1; i = i + 1) { // transmit command

  switch(cmd[i]) {
   case 1: // start
   digitalWrite(txPin, HIGH);
   delayMicroseconds(550);
   digitalWrite(txPin, LOW);
//   Serial.print("s");
   break;
   case 2: // "zero", that is short high spike
   digitalWrite(txPin, LOW);
   delayMicroseconds(110);
   digitalWrite(txPin, HIGH);
//   Serial.print("0");
   break;   
   case 3: // "one", that is long high spike
   digitalWrite(txPin, LOW);
   delayMicroseconds(303);
   digitalWrite(txPin, HIGH);
//   Serial.print("1");
   break;     
   case 4: // pause, that is short low spike
   digitalWrite(txPin, HIGH);
   delayMicroseconds(110);
   digitalWrite(txPin, LOW);
//   Serial.print("p");
   break;     
   case 5: // low, that is long low spike
   digitalWrite(txPin, HIGH);
   delayMicroseconds(290);
   digitalWrite(txPin, LOW);
//   Serial.print("l");   
   break;     
  }
   
  }

}


}


Parts used: Arduino Uno, OOK/ASK transmitter/receiver, simple circuit to record signals on PC, Audacity, Livolo wireless switches.

Special thanks to Nethomeserver author, RC-Switch author and all that good people who were hacking wireless remotes and shared their findings and ideas.
« Last Edit: January 26, 2014, 12:12:04 pm by spch » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26525
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int button1[45]={44,
RAM is a precious resource on an AVR.
You could easily halve your use of it for these tables (use "byte" instead of "int"), or eliminate it altogether (use PROGMEM)
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the clue! I was sure, it is not a good code, but it was ok for me as long as it worked. I'll try it with PROGMEM first, and in case I fail, stick to "byte" type.

Code:
int button1[45]={44,
RAM is a precious resource on an AVR.
You could easily halve your use of it for these tables (use "byte" instead of "int"), or eliminate it altogether (use PROGMEM)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dont suppose you have a guide to connecting the ook ask to the arduino?

I searched around but got a lot of unrelated topics when searching for arduino uno ask smiley-razz

also, thanks a bunch, if i get this working you've potentially saved me a lot of stressing and having to find an alternative to my nice new glass dimmer switches.

I'm also going to pass on your findings to rfxcom and see if theres any chance of them getting the livolo switches working  with the rfxtrx433
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

spch, thanks a lot for sharing.  I've just purchased Livolo switches and am trying to control them from my computer.  Can you share the wiring diagrams of your project?  Thanks in advance for your help.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks a lot
i'm trying to control the livolo switches from  arduino and your code works great !
can you explain the protocol it's working on ?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, thank you for your works. I have got this remote from livolo.
http://www.aliexpress.com/item-img/smart-home-furnishing-life-touch-switches-for-remote-control-VL-RT01/575630281.html

Your works cover button 0 to 10, plus the big "power" button on the top of the remote.

The remote can set scene for a group of lighting switch. Most importantly, the code (0 to 10 button) only give power toggle function, but not power on only function. Under the scene mode, light can be power on only. Can anyone help to study the codes?

I do not have hardware and knowledge to do this myself. If anyone can give me a list of hardware needed. I will also try to learn how to do this.

Thank you
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi folks,

Sorry for not answering questions in timely manner. I didn't get immediate follow up to this post, so I thought that everyone was quite satisfied with initial idea, or not interested at all.

I'v been a bit busy doing some home automation, mostly light automation, of course (but there is auto music in bathroom and automatic wireless cat feeder. All controlled over internet, as you may have guessed smiley-wink

I did my best to answer your questions by PM. Here is a summary for all.

1) Wiring to control switches is extremely simple. Regarding this code: transmitter DATA to Arduino digital pin 9, GND to GND, VCC to 5V.

2) Wiring to record and analyze raw command includes some additional hardware: http://wiki.nethome.nu/lib/exe/detail.php/upm_scheme.png?id=analyzer%3Ahardware and a PC with your favourite audio recording software (I strongly recommend Audactiy)

Here you connect receiver DATA to RECEIVE point, GND to GND and GND of external 5V DC power supply, VCC to external 5V DC power supply.

MIC output should be connected to MIC in of your PC.

Please note that this does not require Arduino. Only receiver, divider, power supply and PC to record and analyze pulses.

3) I didn't try to break into Livolo protocol. Mostly because I don't have the skills to do so. Sorry guys. But I have two recorded raw samples from two different Livolo remotes. That, I guess, shoud be enough to understand protocol.

Here are download links to WAVs with 11 keypresses (order: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, All Off).
http://yadi.sk/d/oDu5rYb9AEtJq
http://yadi.sk/d/psE0boFXAEtFL

4) Here is an automated (sorry) translation of how I did Livolo remote imitation:

http://translate.google.com/translate?sl=auto&tl=en&js=n&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fmysku.ru%2Fblog%2Faliexpress%2F14127.html

Search for "MANAGEMENT Radio switch" in the text to read about Livolo remote imitation.

So, I guess that's all. I'll try to answer your questions if there are any.
« Last Edit: October 01, 2013, 03:01:15 pm by spch » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi thanks for your work,

could you share your latest and impoved code with us?

i copied the codes with audacity , i dont get the same waves, i guess i ll be able to reconstruct the signal thanks to your code

thanks
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
could you share your latest and impoved code with us?

Hi,

Sure. I was going to, anyway. But I didn't do anything to transmitting part, sorry. I've only optimized for memory.

Here is more neat (as I guess) code that should use far less precious RAM than previous. It's been cut from working code, that is why here are only few buttons.

Code:
#include <avr/pgmspace.h> // needed to use PROGMEM

#define  txPin  8 // pin connected to RF transmitter (pin 8)
byte i; // command pulses counter for Livolo (0 - 100)
byte pulse; // counter for command repeat

// commands stored in PROGMEM arrays (see on PROGMEM use here: http://arduino.cc/forum/index.php?topic=53240.0)
// first array element is length of command
const prog_uchar button1[45] PROGMEM ={44, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2};
const prog_uchar button2[43] PROGMEM ={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2};
const prog_uchar button3[41] PROGMEM ={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 5, 3, 4, 2, 4, 2, 4, 2};
const prog_uchar button4[43] PROGMEM ={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2};
const prog_uchar button5[43] PROGMEM ={42, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2};
const prog_uchar button7[41] PROGMEM ={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 5, 3, 4, 2, 4, 2};
const prog_uchar button11[41] PROGMEM ={40, 1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 5, 3, 4, 2, 5, 2, 4, 3, 4, 2};

// pointers to command arrays
PROGMEM const prog_uchar *buttonPointer[] = {button1, button2, button3, button4, button5, button7, button11};

void setup() {

// sipmle example: send button "button2" once. Note that array elements numbered starting from "0" (so button1 is 0, button2 is 1 and so on)

txButton(1);

}

void loop() {
}

// transmitting part
// zeroes and ones here are not actual 0 and 1. I just called these pulses for my own convenience.
// also note that I had to invert pulses to get everything working
// that said in actual command "start pulse" is long low; "zero" = short high; "one" = long high; "pause" is short low; "low" is long low.

void txButton(byte cmd) {
prog_uchar *currentPointer = (prog_uchar *)pgm_read_word(&buttonPointer[cmd]); // current pointer to command array passed as txButton(cmd) argument
byte cmdCounter = pgm_read_byte(&currentPointer[0]); // read array length

for (pulse= 0; pulse <= 180; pulse = pulse+1) { // how many times to transmit a command
for (i = 1; i < cmdCounter+1; i = i + 1) { // counter for reading command array
  byte currentCmd = pgm_read_byte(&currentPointer[i]); // readpulse type from array
  switch(currentCmd) { // transmit pulse
   case 1: // start pulse
   digitalWrite(txPin, HIGH);
   delayMicroseconds(550);
   digitalWrite(txPin, LOW);
   break;
   case 2: // "zero"
   digitalWrite(txPin, LOW);
   delayMicroseconds(110);
   digitalWrite(txPin, HIGH);
   break;   
   case 3: // "one"
   digitalWrite(txPin, LOW);
   delayMicroseconds(303);
   digitalWrite(txPin, HIGH);
   break;     
   case 4: // "pause"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(110);
   digitalWrite(txPin, LOW);
   break;     
   case 5: // "low"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(290);
   digitalWrite(txPin, LOW);
   break;     
  }
  }
 }
 digitalWrite(txPin, LOW);
}

Have fun!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

spch,
quick question, I've done pretty much the same thing with rf remotes but have a problem, if I do a page refresh for whatever reason in the browser, the switches are retriggered again turning them off if they're on and vice versa, are u running your app in a browser and if so have you experienced the same thing and have you been able to correct it, how?  Thanks much....
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

comptrmedic,

I've never experienced such an issue. I'm using web server as in RC-Switch example.

There are, however, certain browser issues. For example, when using Chrome, I need to type command two times to get it working  (I guess that is the way Chrome's cache is working). So when I need to use browser, I prefer Firefox over Chrome.

My best guess is that re-triggering happens because of browser's cache. Try using another browser, or turning off cache (note that this could also slow down your normal browsing). If that doesn't help, there may be something special about web server that is running on your Arduino.

ps. apart from browsers I use Tasker to for direct HTTP POST requests when I need to trigger a switch or change automation settings. I doesn't require to load/reload pages and works flawlessly.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Recently I took another look at the waveform of Livolo remote. And as I had some time to spare, that is what I saw.

1) Each keypress sends remote ID and a command itself (approximately 8000 us, repeated about 100 times or more)
2) Remote ID is unique to the remote and never changes during transmission
3) Each command can be represented by 24 pulses: long start pulse plus 23 data pulses (bits). Of that 23 bits 16 are remote ID and the rest are the command.
4) I've compared commands (7 bit) of two remotes, and they look identical.

Regarding pulses to bits conversion. I took for granted that data pulses are:

1) short highs (I took them as "0")
2) long highs and lows (excluding start pulse) (I took them as "1"). Right, "1" is therefore represented either by long high or long low - doesn't matter

This approach gives exactly 24 pulses (including start) for all avaliable to me commands (buttons 1 to 0). Here is my vision of data packet structure:



Then I thought there must be some kind of a rule which pulses must follow. It looks like:

1) Each data pulse is followed by short low pulse, excluding two long pulses in a row and single long low pulse which is followed by short high
2) First long pulse ("1") is always high, then they are interleaving.

I could have missed something, but first result is simplified code that takes about 200 bytes less memory when compiled for Mega.

Here is an example, which can be further improved (as there is no need to store in command arrays short low pulses):

Code:
#include <avr/pgmspace.h> // needed to use PROGMEM

#define  txPin  8 // pin connected to RF transmitter (pin 8)
byte i; // command pulses counter for Livolo (0 - 100)
byte pulse; // counter for command repeat

// commands stored in PROGMEM arrays (see on PROGMEM use here: http://arduino.cc/forum/index.php?topic=53240.0)
// first array element is length of command
const prog_uchar start[30] PROGMEM = {1, 2, 4, 2, 4, 2, 4, 3, 5, 2, 4, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2}; // remote ID - no need to store it with each command
const prog_uchar button1[15] PROGMEM ={14, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2}; // only command bits
const prog_uchar button2[13] PROGMEM ={12, 5, 3, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2};
const prog_uchar button3[11] PROGMEM ={10, 5, 3, 5, 3, 4, 2, 4, 2, 4, 2};
const prog_uchar button4[13] PROGMEM ={12, 4, 2, 4, 2, 5, 3, 4, 2, 4, 2, 4, 2};
const prog_uchar button5[13] PROGMEM ={12, 5, 2, 4, 3, 4, 2, 4, 2, 4, 2, 4, 2};
const prog_uchar button7[11] PROGMEM ={10, 5, 3, 4, 2, 5, 3, 4, 2, 4, 2};
const prog_uchar button11[11] PROGMEM ={10, 5, 3, 4, 2, 5, 2, 4, 3, 4, 2};

// pointers to command arrays
PROGMEM const prog_uchar *buttonPointer[] = {start, button1, button2, button3, button4, button5, button7, button11};

void setup() {

// sipmle example: send button "button2" once. Note that array elements numbered starting from "0" (so button1 is 0, button2 is 1 and so on)
// Serial.begin(9600);


}

void loop() {

txButton(3);
delay(1000);
}

// transmitting part
// zeroes and ones here are not actual 0 and 1. I just called these pulses for my own convenience.
// also note that I had to invert pulses to get everything working
// that said in actual command "start pulse" is long low; "zero" = short high; "one" = long high; "pause" is short low; "low" is long low.

void txButton(byte cmd) {
prog_uchar *currentPointer = (prog_uchar *)pgm_read_word(&buttonPointer[cmd]); // current pointer to command array passed as txButton(cmd) argument
byte cmdCounter = pgm_read_byte(&currentPointer[0]); // read array length

prog_uchar *currentPointerStart = (prog_uchar *)pgm_read_word(&buttonPointer[0]); // current pointer to start command array


for (pulse= 0; pulse <= 180; pulse = pulse+1) { // how many times to transmit a command
for (i = 0; i<30; i=i+1) {

byte currentCmd = pgm_read_byte(&currentPointerStart[i]);
sendPulse(currentCmd);
// Serial.print(currentCmd);
// Serial.print(", ");
}


for (i = 1; i < cmdCounter+1; i = i + 1) { // counter for reading command array
  byte currentCmd = pgm_read_byte(&currentPointer[i]); // readpulse type from array

  sendPulse(currentCmd);
//  Serial.print(currentCmd);
// Serial.print(", ");
    }
  }
}

void sendPulse(byte txPulse) {

  switch(txPulse) { // transmit pulse
   case 1: // start pulse
   digitalWrite(txPin, HIGH);
   delayMicroseconds(550);
   digitalWrite(txPin, LOW);
   break;
   case 2: // "zero"
   digitalWrite(txPin, LOW);
   delayMicroseconds(110);
   digitalWrite(txPin, HIGH);
   break;  
   case 3: // "one"
   digitalWrite(txPin, LOW);
   delayMicroseconds(303);
   digitalWrite(txPin, HIGH);
   break;      
   case 4: // "pause"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(110);
   digitalWrite(txPin, LOW);
   break;      
   case 5: // "low"
   digitalWrite(txPin, HIGH);
   delayMicroseconds(290);
   digitalWrite(txPin, LOW);
   break;      
  }
 digitalWrite(txPin, LOW);
}

« Last Edit: October 16, 2013, 06:07:40 am by spch » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi spch
I am following your post quite sometime after I bought livolo switch and face same problem.
It is very useful information in your post and codes are working perfectly.
What I am doing right now is, to have more codes ( I wanted around 20 codes to control 20 different switches) by doing try and error method on your codes. I have to admit that it is not successful at all. I cannot get even one more code.
Is it possible to get more codes to control livolo switches and how?

Sorry, I am very new to RF and Arduino.

Regards
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, winnaing,

I'm new to Arduino/RF too smiley-wink

Lately I've been a bit busy with debugging some pieces of code and other things, but I'm planning to rewrite Livolo code since I've studied waveforms more carefully. You could wait a bit, or modify code yourself. I hope the following information would be of use in case you choose the latter.

The key is that command consists of unique remote ID (never changes) and key code (they appear to be fixed too, but change depending on key pressed). So you only need to change remote ID to get more keys, and there are plenty of these "virtual remotes" as each remote ID is 16 bit. Additionally, it is highly probable that Livolo switches can learn key codes other than I've discovered by recording remotes. So there could be even more remote ID and key code combinations.

But the thing is that changing remote ID (or key code) requires following strict rules, i.e.: pulses must interleave, that is high pulse should be always followed by low pulse; two short pulses are "0" and every single long pulse (apart from start) is "1" or vice versa, it doesn't matter as long as you code them right.
Logged

Pages: [1] 2 3 ... 8   Go Up
Jump to: