Исходный текст программы микроконтроллера для приема сообщения от RF-модуля

#define LED_PIN     13

#define HCS_RECIEVER_PIN 2 // пин подключения приемника для брелков

#define RELAY_PIN   12 // пин подключения твердотельного реле

 

class HCS301 {              // класс принятых данных

public:

unsigned BattaryLow: 1; // На брелке села батарейка

unsigned Repeat: 1; // повторная посылка

unsigned BtnNoSound: 1; // кнопка "Без звука"

unsigned BtnOpen: 1; // кнопка "Открыть"

unsigned BtnClose: 1; // кнопка "Закрыть"

unsigned BtnRing: 1; // кнопка "Звонок"

unsigned long SerialNum; // Серийный номер

unsigned long Encript; // Декодирование

void print();        // функция печати класса принятых данных

};

 

volatile boolean HCS_Listening = true;  

byte     HCS_preamble_count = 0;

uint32_t HCS_last_change = 0;

uint32_t HCS_start_preamble = 0;

uint8_t  HCS_bit_counter; // счетчик считанных бит данных

uint8_t  HCS_bit_array[66];  // массив считанных бит данных

#define  HCS_TE 400  // типичная длительность имульса Te

#define  HCS_Te2_3 600  // HCS_TE * 3 / 2

 

HCS301 hcs301;

 

#define HCS_DEBUG_

#ifdef HCS_DEBUG

uint16_t HCS_PulseDuration[12];

uint16_t HCS_BitDuration[66];

uint32_t HCS_msg_duration;

 

struct dta_ {

uint16_t delay;

byte f;

byte st;

};

 

volatile dta_ arr[1000];

volatile int poz_a = 0, poz_b = 0;

#endif //HCS_DEBUG

 

void HCS301::print(){        // функция печати класса принятых данных

String btn;                // подстрока btn для вывода на печать

                                          // если нажата кнопка "Звонок",

if (BtnRing == 1) btn += "Ring";// поместить "Ring" в подстроку вывода

if (BtnClose == 1)  // если нажата кнопка "Закрыть",

{ btn += "Close";          // поместить "Close" в подстроку вывода

digitalWrite(RELAY_PIN, HIGH);}// Включение реле

if (BtnOpen == 1)          // если нажата кнопка "Открыть",

{ btn += "Open";           // поместить "Open" в подстроку вывода

digitalWrite(RELAY_PIN, LOW);} // Выключение реле

if (BtnNoSound == 1) btn += "NoSound";//если нажата кн. "Без звука",

                                                    //помест. "NoSound" в подстроку выв

String it2;                // строка it2 для вывода на печать

 

 

it2 += "Encript ";         // поместить "Encript " в строку вывода

it2 += Encript;            // поместить декодированный код в строку вывода

it2 += " Serial ";         // поместить " Serial " в строку вывода

it2 += SerialNum;          // поместить серийный номер в строку вывода

it2 += " ";

it2 += btn;                // поместить подстроку btn в строку вывода

it2 += " BattaryLow=";     // поместить " BattaryLow=" в строку вывода

it2 += BattaryLow;         // поместить код разряда батареи в строку вывода

it2 += " Rep=";            // поместить " Rep=" в строку вывода

it2 += Repeat;             // поместить количество повторов в строку вывода

 

Serial.println(it2);       // напечатать строку it2

}

 

void setup() {               // начальная настройка

Serial.begin(9600);        // скорость

attachInterrupt(0, HCS_interrupt, CHANGE);// прерывание

pinMode(LED_PIN, OUTPUT); // назначить выходной пин для светодиода

pinMode(RELAY_PIN, OUTPUT); // назначить выходной пин для реле

pinMode(HCS_RECIEVER_PIN, INPUT);//назначить вход. пин для приема

}

 

void loop() {                // рабочий цикл

if(HCS_Listening == false){ // прослушка приемника завершена?

HCS301 msg;              // сообщение для копии класса принятых данных

memcpy(&msg,&hcs301,sizeof(HCS301));// копируем принятые данные

msg.print(); // заполнить подстроку btn и строку it2 для вывода на печать

#ifdef HCS_DEBUG

if(msg.SerialNum!= 639){ // если серийный номер не равен 639

Serial.println("Raw >>>>>>>>>>>>>>>>>>>>>>>");

 

while(1){

   if(poz_b == poz_a) break;

   Serial.println(String(poz_b)+String(" ")+String(arr[poz_b].delay)+\

     String(" ")+String(arr[poz_b].f == 0? "LOW":"HIGH")+String(" ")+\

     String(arr[poz_b].st));

   poz_b++;

}

Serial.println("Data >>>>>>>>>>>>>>>>>>>>>>>");

for(int i = 0;i<66;i++){ Serial.println(HCS_bit_array[i]); }// вывод массива

} else { }                                                                               // битовых данных

poz_a = 0,poz_b = 0;

#endif //HCS_DEBUG

 

HCS_Listening = true;  // продолжить прослушку приемника

}

}

 

void HCS_interrupt(){      // функция-обработчик прерывания

if(HCS_Listening == false){

return;

}

 

uint32_t cur_timestamp = micros(); // текущее время в микросекундах

uint8_t cur_status = digitalRead(HCS_RECIEVER_PIN); // состояние приема

uint32_t pulse_duration = cur_timestamp - HCS_last_change;

HCS_last_change = cur_timestamp; //для опр. продолжительности импульса

 

#ifdef HCS_DEBUG

if(poz_a < 999){

arr[poz_a].delay = pulse_duration;  // продолжительность импульса

 

arr[poz_a].f = cur_status == HIGH? 0: 1;

poz_a++;

}

#endif //HCS_DEBUG

// ловим преамбулу

if(HCS_preamble_count < 12){ // количество импульсов преамбулы < 12?

if(cur_status == HIGH){

  if(((pulse_duration > 200) && (pulse_duration < 400)) || HCS_preamble_count == 0){

   // начало импульса преамбулы

   if(HCS_preamble_count == 0){

     HCS_start_preamble = cur_timestamp; //Отметить время старта

   }                                                            // преамбулы

} else {

   // преамбула не поймана - поймали мусор

   //(неправильная пауза между импульсами)

   HCS_preamble_count = 0;//сброс сч-ка пойманных импульсов преамбулы

   goto exit;

}

} else {

// конец импульса преамбулы

if((pulse_duration > 400) && (pulse_duration < 600)){

   #ifdef HCS_DEBUG

     HCS_PulseDuration[HCS_preamble_count] = pulse_duration;

   #endif //HCS_DEBUG

   // поймали импульс преамбулы

   HCS_preamble_count ++; //увеличить сч-к пойманных имп. преамбулы

   #ifdef HCS_DEBUG

   arr[poz_a-1].st = HCS_preamble_count;

   #endif //HCS_DEBUG

 

   if(HCS_preamble_count == 12){

     // словили преамбулу

     HCS_bit_counter = 0;

     goto exit;

   }

} else {

   // преамбула не поймана - поймали мусор

   HCS_preamble_count = 0; //сброс сч-ка пойманных импульсов преамбулы

   goto exit;

}

}

}

 

// ловим данные

if(HCS_preamble_count == 12){

if(cur_status == HIGH){

if(((pulse_duration > 300) && (pulse_duration < 900)) || HCS_bit_counter == 0){

   // начало импульса данных

} else {

   // неправильная пауза между импульсами

   HCS_preamble_count = 0;

   goto exit;

}

} else {

// конец импульса данных

if((pulse_duration > 300) && (pulse_duration < 900)){

   HCS_bit_array[65 - HCS_bit_counter] = (pulse_duration > HCS_Te2_3)? 0: 1;

    // импульс больше, чем половина от Те * 3 поймали 0, иначе 1

       

      #ifdef HCS_DEBUG 

   HCS_BitDuration[HCS_bit_counter] = pulse_duration;

   #endif

   HCS_bit_counter++; 

   #ifdef HCS_DEBUG   

   arr[poz_a-1].st = HCS_bit_counter;

   #endif //HCS_DEBUG

   if(HCS_bit_counter == 66){

     // поймали все биты данных

     HCS_Listening = false; //отключаем прослушку приемника и отправляем

     // пойманные данные на обработку

     HCS_preamble_count = 0;//сброс сч-ка пойманных имп. преамбулы

     #ifdef HCS_DEBUG       

     HCS_msg_duration = cur_timestamp - HCS_start_preamble;

     #endif //HCS_DEBUG

 

     hcs301.Repeat = HCS_bit_array[0]; // заполнить класс принятых данных

     hcs301.BattaryLow = HCS_bit_array[1]; // из битового массива

     hcs301.BtnNoSound = HCS_bit_array[2];

     hcs301.BtnOpen = HCS_bit_array[3];

     hcs301.BtnClose = HCS_bit_array[4];

     hcs301.BtnRing = HCS_bit_array[5];

 

     hcs301.SerialNum = 0;     // заполнить серийный номер

     for(int i = 6; i < 34;i++){ //из битового массива

       hcs301.SerialNum = (hcs301.SerialNum << 1) + HCS_bit_array[i];

     };

 

     uint32_t Encript = 0;        // заполнить декодированный код

     for(int i = 34; i < 66;i++){ //из битового массива

 

        Encript = (Encript << 1) + HCS_bit_array[i];

     };

     hcs301.Encript = Encript;

   }

} else {

   // поймали мусор - отключаемся

   HCS_preamble_count = 0;

   goto exit;

 }

}

}

exit:;

//digitalWrite(LED_PIN,cur_status); // вывод текущего состояния вычитки

}                                                  // приемника на светодиод

 

 

Примечание: Для вывода в MajorDomo дополнить программу HTTP-запросом:

char http_buf[120];

sprintf(http_buf, "GET

/objects/?script=easyRF&uid=%u&d0=%u&d1=%u&d2=%u HTTP/1.0",

(int)unique_device_id), (int)inv[0], (int)inv[1], (int)inv[2];

Serial.print(http_buf);  // Выводим строку со ссылкой HTTP-запроса

Serial.println();

 

Приложение В


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: