Приемник сигналов с брелков CAME 433.92 MГц.

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Всем привет!

Купил я на алиэкспресе недорогой всего 50 урблей приемопередатчик на 433 мгц,

 

с целью заменить им установленый у меня в машине блок управления везными воротами на 315 мгц ( хоме линк) это американская система.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Мы рады за Вас. С удачной покупкой!

Волшебник
Offline
Зарегистрирован: 22.12.2016

Тонкий американский юмор?

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Да, это была хорошая шутка!

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

ЕвгенийП пишет:

Мы рады за Вас. С удачной покупкой!

По началу я тоже так подумал, но приемник ни как не хотел принемать сигналы с брелка, вернее приемник принемал сигналы, было видно по осцилографу, но вот программа которую я использовал для декодирования сигналов отказывалась их распозновать. И как я понял, не только у меня а  у всех кто приобрел данные приемники был тот же результат!

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Вот фото этого чудо приемника и передатчика!!! У этого комплекта есть особеность что приемник работает от 3,5 до 6 вольт а а передатчик от 2 до 3,6 вольт. Зато размеры у них очень маленькие, и приемник имеет очень хорошую чуствительность.

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Для декодирования сигналов с брлков CAME я использовал скетч

#define pinRX 2
#define pinTX 8

#define CM_MAX_TE 450
#define CM_MIN_TE 250
#define CM_BITS12 12
#define CM_BITS24 24
#define Te 320

volatile byte level = 255;
volatile unsigned long last;
volatile unsigned long len;
byte p_level;
unsigned long p_len;
unsigned long p_len_prev;
struct
{
    uint8_t state;
    uint8_t data[3], dat_bit;
} came;


void setup()
{
    Serial.begin(9600);
    while (!Serial);
    attachInterrupt(0, pinRX_int, CHANGE);
    pinMode(pinTX, OUTPUT);
    interrupts();
}

void loop()
{
    ////прием
    RfReceive();

    ////передача
    char *code = "000000000000"; // 0-0
    ///char *code = "000000000000000000000000"; // 0-0-0
   RfTransmitt(code, 4);
    delay(2000); // сделать паузу между отправками
}

void RfReceive()
{
    if (level != 255)
    {
        noInterrupts();
        p_level = level;
        p_len = len;
        len = 0;
        level = 255;
        interrupts();
        process_came();
        p_len_prev = p_len;
    }
    if (came.state == 100)
    {
        for (int i = 0; i < sizeof(came.data) - (came.dat_bit == CM_BITS12 ? 1 : 0); i++) {
            if (i > 0) {
                Serial.print("-");
            }
            Serial.print(stringWithPrefix(String(came.data[i], BIN), came.dat_bit == CM_BITS12 ? 6 : 8, '0'));
        }
        came.state = 0;
        Serial.println();
    }
}

void RfTransmitt(char *codeString, unsigned int numberOfShipments)
{
    int codeLength = strlen(codeString);
    if (codeLength != 12 && codeLength != 24)
    {
        Serial.println("incorrect code.");
        return;
    }

    byte code[codeLength];
    for (int i = 0; i < codeLength; i++) {
        code[i] = codeString[i] == '0' ? 0 : 1;
    }

    byte codeUpdate[codeLength];

    int number = 0;

    switch (codeLength) {
    case 12:
        //оратный порядок
        for (int i = 5; i >= 0; i--) {
            codeUpdate[number] = code[i];
            Serial.print(codeUpdate[number]);
            number++;
        }
        Serial.print(" ");
        //прямой порядок
        for (int i = 6; i < 12; i++) {
            codeUpdate[number] = code[i];
            Serial.print(codeUpdate[number]);
            number++;
        }
        break;
    case 24:
        //оратный порядок для всех символов
        for (int i = 1; i <= 3; i++) {
            for (int j = i * 8 - 1; j >= 8 * (i - 1); j--) {
                codeUpdate[number] = code[j];
                Serial.print(codeUpdate[number]);
                number++;
            }
            Serial.print("-");
        }
        break;
    }

    Serial.println();

    for (int i = 0; i < numberOfShipments; i++) // посылку посылаем как и брелок - NS раза подряд.
    {
        digitalWrite(pinTX, HIGH);
        delayMicroseconds(Te);
        digitalWrite(pinTX, LOW); // посылаем стартовый импульс
        for (int j = 0; j < codeLength; j++) {
            SendCameBit(codeUpdate[j]); // побитово перебираем и посылаем код
        }
        delay(16);
    }
}

void pinRX_int()
{
    if (level != 255) return;
    len = micros() - last;
    last = micros();
    if (digitalRead(pinRX) == HIGH) level = 0;
    else level = 1;
}

void process_came()
{
    unsigned char b;

    switch (came.state)
    {
    case 0:
        if (p_level) break;
        came.state = 1;
        break;
    case 1: //start
        if (!p_level) break;

        else if (p_len >= CM_MIN_TE && p_len <= CM_MAX_TE)
        {
            came.state = 2;
            came.dat_bit = 0;

            for (int i = 0; i < sizeof(came.data); i++) {
                came.data[i] = 0x00;
            }

        }
        else came.state = 0;
    case 2: //dat
        if (p_level)
        {
            if (came.dat_bit == CM_BITS24)
            {
                came.state = 0;
                break;
            }

            if (p_len_prev <= CM_MAX_TE && p_len_prev >= CM_MIN_TE &&
                    p_len <= CM_MAX_TE * 2 && p_len >= CM_MIN_TE * 2) b = 0;
            else if (p_len_prev <= CM_MAX_TE * 2 && p_len_prev >= CM_MIN_TE * 2 &&
                     p_len <= CM_MAX_TE && p_len >= CM_MIN_TE) b = 1;
            else
            {
                came.state = 0;
                break;
            }

            if (b) set_bit(came.data, came.dat_bit);
            came.dat_bit++;
            break;
        }
        else
        {
            if ((p_len > 5000) && (came.dat_bit == CM_BITS12 || came.dat_bit == CM_BITS24)) came.state = 100;
        }
        break;
    }
}

void SendCameBit(byte b)
{
    delayMicroseconds(Te);
    if (!b) digitalWrite(pinTX, HIGH);
    delayMicroseconds(Te);
    digitalWrite(pinTX, HIGH);
    delayMicroseconds(Te);
    digitalWrite(pinTX, LOW);
}

void set_bit(uint8_t *data, uint8_t n)
{
    data[n / 8] |= 1 << (n % 8);
}

String stringWithPrefix(String line, int len, char prefix)
{
    String addon = "";
    int n = len - line.length();
    for (int i = 0; i < n; i++) {
        addon += prefix;
    }
    return addon + line;
}

кем то написанный, к сожалению уже не помню и не могу сослаться на автора, сам автор утверждал что скетч абсолютно рабочий.  

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016
b707
Offline
Зарегистрирован: 26.05.2017

Простите, правильно ли я понял, что Вы собрались приемником 433 МГц записывать сигналы 315МГц? Не проще ли было купить сразу примник 315МГц

russo
Offline
Зарегистрирован: 20.11.2014

Вы уверенны что у вас CAME протокол обмена?

Нужно анализатором посмотреть для начала посылки с пульта, определить форматы пакетов

Можно фото брелка выложить

 

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

b707 пишет:

Простите, правильно ли я понял, что Вы собрались приемником 433 МГц записывать сигналы 315МГц? Не проще ли было купить сразу примник 315МГц

Прощаю! Поняли вы меня не совсем верно, повторяю, у меня в машине установлен блок управления гаражными воротами (home link) с частотой 315 мгц. это американский стандарт, так как машина из Америки. Я планирую его полностью выкинуть и собрать свой аналогичный блок только с частотой 433 мгц. для управления европейскими воротами "САМЕ" Для чего я и приобрёл комплект приемопередатчика на частоту 433, и ардунку!

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

russo пишет:

Вы уверенны что у вас CAME протокол обмена?

Нужно анализатором посмотреть для начала посылки с пульта, определить форматы пакетов

Можно фото брелка выложить

 

Сигналы с брелка приемник принемает, я наблюдаю их на осцилографе. Выкладываю фото брелка.

russo
Offline
Зарегистрирован: 20.11.2014

Саме представленый на фото имеет статический код, достаточно один раз записать и можно пользоваться постоянно.

http://phreakerclub.com/1129

http://phreakerclub.com/forum/showthread.php?t=1940

http://phreakerclub.com/forum/showpost.php?p=32162&postcount=997

http://phreakerclub.com/forum/showthread.php?t=1583

http://phreakerclub.com/forum/showthread.php?t=1425

В общем для гаража я бы не применял каме. Придумал бы свой протокол и ушел бы от частоты 433.92 МГц

для этого взял бы радиомодули CC1101 или Si4432, но они с уровнями 3.3 вольта с SPI интерфейсом.

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

russo пишет:

Саме представленый на фото имеет статический код, достаточно один раз записать и можно пользоваться постоянно.

http://phreakerclub.com/1129

http://phreakerclub.com/forum/showthread.php?t=1940

http://phreakerclub.com/forum/showpost.php?p=32162&postcount=997

http://phreakerclub.com/forum/showthread.php?t=1583

http://phreakerclub.com/forum/showthread.php?t=1425

В общем для гаража я бы не применял каме. Придумал бы свой протокол и ушел бы от частоты 433.92 МГц

для этого взял бы радиомодули CC1101 или Si4432, но они с уровнями 3.3 вольта с SPI интерфейсом.

Спасибо за информацию, я делаю потому что есть еще несколько, а точнее довольно много ворот "САМЕ" которые надо открывать! И все они сстатическим кодом. Сейчас "САМЕ" тоже используют технологию прыгающего кода KeeLoq, вот что с ними делать ума не приложу!

russo
Offline
Зарегистрирован: 20.11.2014

Если нужен универсальный пульт для разных шлагбаймов, то можете купить уже готовый

http://phreaker.pro/forum/showthread.php?t=9503

Можно импользовать не только для своего дома )

Если будете цену спрашивать, просьба подскажите по чем у них эти устройства.

russo
Offline
Зарегистрирован: 20.11.2014

http://phreakerclub.com/forum/showthread.php?t=1583

на второй странице есть папка с проэктом в протеусе с имитатором сигналов шлагов, можно отладку делать

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

russo пишет:

Если нужен универсальный пульт для разных шлагбаймов, то можете купить уже готовый

http://phreaker.pro/forum/showthread.php?t=9503

Можно импользовать не только для своего дома )

Если будете цену спрашивать, просьба подскажите по чем у них эти устройства.

Да нужен, универсальный пуль, но  встроенный в машину, на место штатного пульта. Покупать что бы потом его переделывать в штатный я не буду, коли все равно ковыряться, поэтому  буду делать все сам до конца. 

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

russo пишет:

http://phreakerclub.com/forum/showthread.php?t=1583

на второй странице есть папка с проэктом в протеусе с имитатором сигналов шлагов, можно отладку делать

Спасибо за сылку посмотрю!

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Как я уже писал данный комплект приемника и передатчика по какой-то причине не заработал с ранее написанными скетчем декодирования сигналов с брелков "CAME"  что были выложены. Вот например скетч который использовал я.

#define pinRX 2
#define pinTX 8

#define CM_MAX_TE 450
#define CM_MIN_TE 250
#define CM_BITS12 12
#define CM_BITS24 24
#define Te 320

volatile byte level = 255;
volatile unsigned long last;
volatile unsigned long len;
byte p_level;
unsigned long p_len;
unsigned long p_len_prev;
struct
{
    uint8_t state;
    uint8_t data[3], dat_bit;
} came;


void setup()
{
    Serial.begin(9600);
    while (!Serial);
    attachInterrupt(0, pinRX_int, CHANGE);
    pinMode(pinTX, OUTPUT);
    interrupts();
}

void loop()
{
    ////прием
    RfReceive();

    ////передача
    char *code = "000000000000"; // 0-0
    ///char *code = "000000000000000000000000"; // 0-0-0
   RfTransmitt(code, 4);
    delay(2000); // сделать паузу между отправками
}

void RfReceive()
{
    if (level != 255)
    {
        noInterrupts();
        p_level = level;
        p_len = len;
        len = 0;
        level = 255;
        interrupts();
        process_came();
        p_len_prev = p_len;
    }
    if (came.state == 100)
    {
        for (int i = 0; i < sizeof(came.data) - (came.dat_bit == CM_BITS12 ? 1 : 0); i++) {
            if (i > 0) {
                Serial.print("-");
            }
            Serial.print(stringWithPrefix(String(came.data[i], BIN), came.dat_bit == CM_BITS12 ? 6 : 8, '0'));
        }
        came.state = 0;
        Serial.println();
    }
}

void RfTransmitt(char *codeString, unsigned int numberOfShipments)
{
    int codeLength = strlen(codeString);
    if (codeLength != 12 && codeLength != 24)
    {
        Serial.println("incorrect code.");
        return;
    }

    byte code[codeLength];
    for (int i = 0; i < codeLength; i++) {
        code[i] = codeString[i] == '0' ? 0 : 1;
    }

    byte codeUpdate[codeLength];

    int number = 0;

    switch (codeLength) {
    case 12:
        //оратный порядок
        for (int i = 5; i >= 0; i--) {
            codeUpdate[number] = code[i];
            Serial.print(codeUpdate[number]);
            number++;
        }
        Serial.print(" ");
        //прямой порядок
        for (int i = 6; i < 12; i++) {
            codeUpdate[number] = code[i];
            Serial.print(codeUpdate[number]);
            number++;
        }
        break;
    case 24:
        //оратный порядок для всех символов
        for (int i = 1; i <= 3; i++) {
            for (int j = i * 8 - 1; j >= 8 * (i - 1); j--) {
                codeUpdate[number] = code[j];
                Serial.print(codeUpdate[number]);
                number++;
            }
            Serial.print("-");
        }
        break;
    }

    Serial.println();

    for (int i = 0; i < numberOfShipments; i++) // посылку посылаем как и брелок - NS раза подряд.
    {
        digitalWrite(pinTX, HIGH);
        delayMicroseconds(Te);
        digitalWrite(pinTX, LOW); // посылаем стартовый импульс
        for (int j = 0; j < codeLength; j++) {
            SendCameBit(codeUpdate[j]); // побитово перебираем и посылаем код
        }
        delay(16);
    }
}

void pinRX_int()
{
    if (level != 255) return;
    len = micros() - last;
    last = micros();
    if (digitalRead(pinRX) == HIGH) level = 0;
    else level = 1;
}

void process_came()
{
    unsigned char b;

    switch (came.state)
    {
    case 0:
        if (p_level) break;
        came.state = 1;
        break;
    case 1: //start
        if (!p_level) break;

        else if (p_len >= CM_MIN_TE && p_len <= CM_MAX_TE)
        {
            came.state = 2;
            came.dat_bit = 0;

            for (int i = 0; i < sizeof(came.data); i++) {
                came.data[i] = 0x00;
            }

        }
        else came.state = 0;
    case 2: //dat
        if (p_level)
        {
            if (came.dat_bit == CM_BITS24)
            {
                came.state = 0;
                break;
            }

            if (p_len_prev <= CM_MAX_TE && p_len_prev >= CM_MIN_TE &&
                    p_len <= CM_MAX_TE * 2 && p_len >= CM_MIN_TE * 2) b = 0;
            else if (p_len_prev <= CM_MAX_TE * 2 && p_len_prev >= CM_MIN_TE * 2 &&
                     p_len <= CM_MAX_TE && p_len >= CM_MIN_TE) b = 1;
            else
            {
                came.state = 0;
                break;
            }

            if (b) set_bit(came.data, came.dat_bit);
            came.dat_bit++;
            break;
        }
        else
        {
            if ((p_len > 5000) && (came.dat_bit == CM_BITS12 || came.dat_bit == CM_BITS24)) came.state = 100;
        }
        break;
    }
}

void SendCameBit(byte b)
{
    delayMicroseconds(Te);
    if (!b) digitalWrite(pinTX, HIGH);
    delayMicroseconds(Te);
    digitalWrite(pinTX, HIGH);
    delayMicroseconds(Te);
    digitalWrite(pinTX, LOW);
}

void set_bit(uint8_t *data, uint8_t n)
{
    data[n / 8] |= 1 << (n % 8);
}

String stringWithPrefix(String line, int len, char prefix)
{
    String addon = "";
    int n = len - line.length();
    for (int i = 0; i < n; i++) {
        addon += prefix;
    }
    return addon + line;
}

Я стал разбираться в сути проблемы, потому как наосциллографе я наблюдал четкий меандр на выходе с приемника. Я нашел в интернете еще одного бедолагу который также как и я не смог запустить данный комплект. Он списался с поставщиком из Китая и он ему выслал зараженный архив с PDF файлом datasheet на чисто китайском языке, но из которого мне все таки удалось понять что у используемой микросхемы есть 2 вывода коррекции скорости приема сигнала, и они установлены в среднее положение. Я перепаял выводы непосредственно на плате приемника, так что была максимальная скорость приема сигнала.И о чудо, у меня все заработало! Но !!!!!!! Перед тем как это чудо состоялось нужно сначала запустить вот такой скетч!

//код работает,выдает длительность импульсов.
int rxPin = 2;  
volatile static unsigned long m=0;
volatile long lastLow=0;
volatile long lastHigh=0;
boolean preambula=0;
  
void setup() {
attachInterrupt(0, grab, CHANGE);
Serial.begin(115200);
 Serial.println("MEGA ARDUINO LOGGER"); 
   Serial.println("CAME"); 
}
 
void loop() {
 
if (lastLow>14500){preambula=1;lastLow=0;}
if (lastHigh>0&&lastHigh<350){preambula=0;} 
if (lastHigh>250&&lastHigh<390&&preambula==1){
preambula=0;
lastHigh=0;
Serial.println("");

 
for (int k=0;k<24;){
if (lastLow>0)
{Serial.print(lastLow);
Serial.print("L,");
lastLow=0;
k=k+1;}
 
if (lastHigh>0)
{Serial.print(lastHigh);
Serial.print("H,");
lastHigh=0;
k=k+1;}
}
}
}
 
void grab()
{
    if (digitalRead(rxPin) == HIGH){lastLow=micros()-m;}
    else{lastHigh=micros()-m;}
    m=micros();
}

Он выдает вместо кода брелка длительности посылок, минимальные и максимальные.

Находим самые короткие "252"и самые длинные "14744". Эти длительности нужно запомнить и заменить в своем скетче в частности в выделеные строки:

#define pinRX 2
#define pinTX 8

#define CM_MAX_TE 450
#define CM_MIN_TE 250
#define CM_BITS12 12
#define CM_BITS24 24
#define Te 320

Нужно брать длительность с сзапасом минимальную делать 230, а максимальную 15000.

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

удалено

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Андрей, Вы бы сейчас собрали в один пост правильный скетч, даташит и всё остальное, типа как "резюме всё в одном". Тема-то не раз всплывала и, уверен, не одном человеку ещё пригодится.

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

ЕвгенийП пишет:

Андрей, Вы бы сейчас собрали в один пост правильный скетч, даташит и всё остальное, типа как "резюме всё в одном". Тема-то не раз всплывала и, уверен, не одном человеку ещё пригодится.

Ок. Так и сделаю. Но только чуть позже. Возможно и видео сниму как все работает.

dtvims
Offline
Зарегистрирован: 26.11.2012

Н_Андрей_Ю пишет:

А что конкретно Вы перепаяли?

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

dtvims пишет:
Н_Андрей_Ю пишет:
А что конкретно Вы перепаяли?
Ну как тебе сказать? У микросхемы приемника есть две ноги для коррекции скорости приема сигнала, В описании  datasheet на эту микросхему приемника что я выложил выше, дана таблица истинности для коррекции скорости. Я сравнил информацию из таблицы и то как были распаяны на плате ножки микросхемы у меня, и выяснил что, у меня установлена средняя скорость приема. Я перепаял ножки так чтобы была максимальная скорость. Вот и все!

dtvims
Offline
Зарегистрирован: 26.11.2012

Я надеялся на картинку, но полистав datasheet сам нашел. По любому спасибо. Сам уже давно пытался понять, почему эти приемники не читают данные брелки...

Н_Андрей_Ю
Н_Андрей_Ю аватар
Offline
Зарегистрирован: 22.12.2016

Выкладываю еще один интересный скетч для изучения.

#define rxPin 2 //пин приемника

void setup()
{
pinMode(rxPin, INPUT);
Serial.begin(115200); 
Serial.println("Came started");
attachInterrupt(0, grab, CHANGE); 
interrupts();
}

volatile static long lastCode = 0;

void loop() {
if (lastCode > 0)
{
Serial.println(lastCode);
lastCode = 0;
}
}

#define MAX_DELTA 200
boolean CheckValue(unsigned int base, unsigned int value)
{
return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA)));
}
volatile unsigned long prevtime;
volatile unsigned int lolen, hilen, state;
volatile static byte cameCounter = 0; // count of bits stored
volatile static long cameCode = 0; // code itself

void grab() {
state = digitalRead(rxPin);
if (state == HIGH)
lolen = micros() - prevtime;
else
hilen = micros() - prevtime;
prevtime = micros();

if (state == LOW)
{
// последовательность закончилась
if (CheckValue(320, hilen) && CheckValue(640, lolen)) // valid 1
{
cameCode = (cameCode << 1) | 1;
cameCounter++;
}
else if (CheckValue(640, hilen) && CheckValue(320, lolen)) // valid 0
{
cameCode = (cameCode << 1) | 0;
cameCounter++;
}
else cameCounter = 0;
} else 
if (lolen > 1000 && (cameCounter == 24) 
{
lastCode = cameCode & 0xfff;
cameCounter = 0;
cameCode = 0;
}
if (lastCode == 432) 
{
 time1=millis()-time;
 if(time1>200) digitalWrite(13, !digitalRead(13));
 time = millis();  
}
}

 

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Н_Андрей_Ю пишет:

Выкладываю еще один интересный скетч для изучения.

#define rxPin 2 //пин приемника

void setup()
{
pinMode(rxPin, INPUT);
Serial.begin(115200); 
Serial.println("Came started");
attachInterrupt(0, grab, CHANGE); 
interrupts();
}

volatile static long lastCode = 0;

void loop() {
if (lastCode > 0)
{
Serial.println(lastCode);
lastCode = 0;
}
}

#define MAX_DELTA 200
boolean CheckValue(unsigned int base, unsigned int value)
{
return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA)));
}
volatile unsigned long prevtime;
volatile unsigned int lolen, hilen, state;
volatile static byte cameCounter = 0; // count of bits stored
volatile static long cameCode = 0; // code itself

void grab() {
state = digitalRead(rxPin);
if (state == HIGH)
lolen = micros() - prevtime;
else
hilen = micros() - prevtime;
prevtime = micros();

if (state == LOW)
{
// последовательность закончилась
if (CheckValue(320, hilen) && CheckValue(640, lolen)) // valid 1
{
cameCode = (cameCode << 1) | 1;
cameCounter++;
}
else if (CheckValue(640, hilen) && CheckValue(320, lolen)) // valid 0
{
cameCode = (cameCode << 1) | 0;
cameCounter++;
}
else cameCounter = 0;
} else 
if (lolen > 1000 && (cameCounter == 24) 
{
lastCode = cameCode & 0xfff;
cameCounter = 0;
cameCode = 0;
}
if (lastCode == 432) 
{
 time1=millis()-time;
 if(time1>200) digitalWrite(13, !digitalRead(13));
 time = millis();  
}
}

 

По такому принципу можно не только Кейм,но и старлайн прнимать.Знаком очень стиль и метод,догадываюсь откуда исходники ))