Приемник сигналов с брелков CAME 433.92 MГц.
- Войдите на сайт для отправки комментариев
Ср, 24/05/2017 - 17:27
Всем привет!
Купил я на алиэкспресе недорогой всего 50 урблей приемопередатчик на 433 мгц,
с целью заменить им установленый у меня в машине блок управления везными воротами на 315 мгц ( хоме линк) это американская система.
Мы рады за Вас. С удачной покупкой!
Тонкий американский юмор?
Да, это была хорошая шутка!
Мы рады за Вас. С удачной покупкой!
Вот фото этого чудо приемника и передатчика!!! У этого комплекта есть особеность что приемник работает от 3,5 до 6 вольт а а передатчик от 2 до 3,6 вольт. Зато размеры у них очень маленькие, и приемник имеет очень хорошую чуствительность.
Для декодирования сигналов с брлков 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; }кем то написанный, к сожалению уже не помню и не могу сослаться на автора, сам автор утверждал что скетч абсолютно рабочий.
Прошу помощи в написании функции "Проверка данных на уникальность перед записью в ЕЕПРОМ"
Простите, правильно ли я понял, что Вы собрались приемником 433 МГц записывать сигналы 315МГц? Не проще ли было купить сразу примник 315МГц
Вы уверенны что у вас CAME протокол обмена?
Нужно анализатором посмотреть для начала посылки с пульта, определить форматы пакетов
Можно фото брелка выложить
Простите, правильно ли я понял, что Вы собрались приемником 433 МГц записывать сигналы 315МГц? Не проще ли было купить сразу примник 315МГц
Вы уверенны что у вас CAME протокол обмена?
Нужно анализатором посмотреть для начала посылки с пульта, определить форматы пакетов
Можно фото брелка выложить
Саме представленый на фото имеет статический код, достаточно один раз записать и можно пользоваться постоянно.
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 интерфейсом.
Саме представленый на фото имеет статический код, достаточно один раз записать и можно пользоваться постоянно.
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 интерфейсом.
Если нужен универсальный пульт для разных шлагбаймов, то можете купить уже готовый
http://phreaker.pro/forum/showthread.php?t=9503
Можно импользовать не только для своего дома )
Если будете цену спрашивать, просьба подскажите по чем у них эти устройства.
http://phreakerclub.com/forum/showthread.php?t=1583
на второй странице есть папка с проэктом в протеусе с имитатором сигналов шлагов, можно отладку делать
Если нужен универсальный пульт для разных шлагбаймов, то можете купить уже готовый
http://phreaker.pro/forum/showthread.php?t=9503
Можно импользовать не только для своего дома )
Если будете цену спрашивать, просьба подскажите по чем у них эти устройства.
http://phreakerclub.com/forum/showthread.php?t=1583
на второй странице есть папка с проэктом в протеусе с имитатором сигналов шлагов, можно отладку делать
Как я уже писал данный комплект приемника и передатчика по какой-то причине не заработал с ранее написанными скетчем декодирования сигналов с брелков "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". Эти длительности нужно запомнить и заменить в своем скетче в частности в выделеные строки:
Нужно брать длительность с сзапасом минимальную делать 230, а максимальную 15000.
удалено
Андрей, Вы бы сейчас собрали в один пост правильный скетч, даташит и всё остальное, типа как "резюме всё в одном". Тема-то не раз всплывала и, уверен, не одном человеку ещё пригодится.
Андрей, Вы бы сейчас собрали в один пост правильный скетч, даташит и всё остальное, типа как "резюме всё в одном". Тема-то не раз всплывала и, уверен, не одном человеку ещё пригодится.
А что конкретно Вы перепаяли?
Я надеялся на картинку, но полистав datasheet сам нашел. По любому спасибо. Сам уже давно пытался понять, почему эти приемники не читают данные брелки...
Выкладываю еще один интересный скетч для изучения.
#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(); } }Выкладываю еще один интересный скетч для изучения.
#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(); } }По такому принципу можно не только Кейм,но и старлайн прнимать.Знаком очень стиль и метод,догадываюсь откуда исходники ))