Клонирование пультов от ворот CAME

alex0
Offline
Зарегистрирован: 14.12.2015

Всем привет. Помогите пожалуйста.

Хочу сделать устройство на базе атмеги 328 которое сможет запомнить все мои ключи CAME(15 штук) и воспроизводить их коды.

Удалось найти нужные скетчи на Youtube 

https://www.youtube.com/watch?v=-68WsZhl-PE Приемник

#define RX 2 
#define TIMER_DIV 
volatile byte level=255; 
volatile unsigned long last, len; 
byte p_level; 
unsigned long p_len, p_len_prev; 
struct  
{  
  uint8_t state;  
  uint8_t data[3], dat_bit;  
} came;  
void set_bit(uint8_t *data, uint8_t n) 
{ 
  data[n/8]|=1<<(n%8); 
} 


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

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;  
        came.data[0]=0x00;  
        came.data[1]=0x00;  
        came.data[2]=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 dump_hex(byte *buf, byte bits) 
{ 
byte b; 

for(b=0; b>(bits+7)/8; b++) 
{ 
if(buf[b]>0x0f) Serial.print('0'); 
Serial.print(buf[b], HEX); 
Serial.print(" "); 
} 
Serial.println(""); 
} 
void rx_int() 
{ 
if(level!=255) return; 

len=micros()-last; 
last=micros(); 

if(digitalRead(RX)==HIGH) level=0; 
else level=1;  
} 
void setup() 
{  
attachInterrupt(0, rx_int, CHANGE); 

Serial.begin(115200);  
while(!Serial); 

Serial.println("MEGA ARDUINO LOGGER"); 
Serial.println(""); 

interrupts(); 
}  

byte b; 

void loop() 
{  
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) 
{ 
Serial.print(came.data[0],BIN);
Serial.print(":");  
Serial.print(came.data[1],BIN); 
Serial.print(":");  
Serial.print(came.data[2],BIN);
Serial.print(":");   
//Serial.print("CAME["); 
Serial.print("_came["); 
Serial.print(came.dat_bit); 
Serial.print("]: "); 
dump_hex(came.data, came.dat_bit); 
came.state=0; 
} 
}  

https://www.youtube.com/watch?v=eaTVHAXhCRg Передатчик

#define txPin 8
#define Te 320

void setup(){
  pinMode(txPin, OUTPUT);
}

void loop()
{
  SendCame(0b100010001111);
}

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

void SendCame(long Code)
{     
  for (int j=0;j<5;j++) // посылку посылаем как и брелок - 4 раза подряд.
  {
    digitalWrite(txPin,HIGH);
    delayMicroseconds(Te);
    digitalWrite(txPin,LOW);// посылаем стартовый импульс
    
    for (byte i=12;i>0;i--){
      SendCameBit(bitRead(Code, i-1)); // побитово перебираем и посылаем код
    }
    delay(16);
  }
  delay(2000); // сделать паузу после посылки на 2 с
}

 

По отдельности оба этих скетча прекрасно работают, но хочется их объеденить чтобы при нажатии первой кнопки устройство считывало код и сохраняло в EEPROM, а при нажатии второй кнопки отправляло код из EEPROM.

За три дня мне не удалось добится ничего. В моей задумке При нажатии одной кнопки обрабатывается Loop из первого скетча, при нажатии другой кнопки Loop из второго скетча. Но компилятор ругется на то что я не задал функцию. Еще я не знаю как из трёх значений "came.data[]" сделать одно котороее буду сохранять в EEPROM. 

Мои потуги

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define RX 2   // Пин приемника
#define TIMER_DIV
#define butt1 18  // Кнопка 1
#define butt2 19  // Кнопка 2
byte buttState1 = 0;
byte buttState2 = 0;
byte qq = 0;
byte mode = 0;

#define txPin 16  // Пин передатчика
#define Te 320  // Задержка побитовой передачи
unsigned long incomingByte;

LiquidCrystal_I2C lcd1(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Назначаем дисплей

volatile byte level = 255;
volatile unsigned long last, len;
byte p_level;
unsigned long p_len, p_len_prev;
struct
{
  uint8_t state;
  uint8_t data[3], dat_bit;
} came;
void set_bit(uint8_t *data, uint8_t n)  //--------------------------------------------------------------------------------------------------
{
  data[n / 8] |= 1 << (n % 8);
}


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

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;
        came.data[0] = 0x00;
        came.data[1] = 0x00;
        came.data[2] = 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 dump_hex(byte *buf, byte bits)  //----------------------------------------------------------------------------------------------
{
  byte b;

  for (b = 0; b > (bits + 7) / 8; b++)
  {
    if (buf[b] > 0x0f) Serial.print('0');
    Serial.print(buf[b], HEX);
    Serial.print(" ");
  }
  Serial.println("");
}
void rx_int()       //---------------------------------------------------------------------------------------------------------------
{
  if (level != 255) return;

  len = micros() - last;
  last = micros();

  if (digitalRead(RX) == HIGH) level = 0;
  else level = 1;
}
void setup()  //----------------------------------------------------------------------------------------------------------------------
{
  lcd1.begin(20, 4);

  attachInterrupt(0, rx_int, CHANGE);

  Serial.begin(115200);
  //while (!Serial);

  pinMode(butt1, INPUT_PULLUP);
  pinMode(butt2, INPUT_PULLUP);
  pinMode(txPin, OUTPUT);

}


void loop()  //------------------------------------------------------------------------------------------------------------------------
{
  noInterrupts();
  if (!qq)
  {
    lcd1.print("loop");
    qq = 1;
  }
  buttState1 = digitalRead(butt1);
  buttState2 = digitalRead(butt2);
  if (buttState1 == 0) 
  {
  transmission (); // exit status 1  'transmission' was not declared in this scope   <<<<<<<<<<<<<<<<<<<<<<<<<< Компилятор выдает ошибку
  }
  if (buttState2 == 0) receiving();


  void transmission ()    //----------------------------------------------------------------------------------------------------
  {
    noInterrupts();
    lcd1.clear();
    lcd1.setCursor(0, 0);
    lcd1.print("TRANSMISSION");
    SendCame(0b101010111000);
  }

  void receiving ()  //------------------------------------------------------------------------------------------------------------
  {
    interrupts();

    lcd1.clear();
    lcd1.setCursor(0, 0);
    lcd1.print("RECEIVING");

    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)
    {
      lcd1.setCursor(0, 1);
      lcd1.print(came.data[0], BIN);
      lcd1.print(came.data[1], BIN);
      lcd1.print(came.data[2], BIN);
      lcd1.print("_came[");
      lcd1.print(came.dat_bit);
      lcd1.print("]: ");
      dump_hex(came.data, came.dat_bit);
      came.state = 0;
    }
  }

}
}

void SendCameBit(byte b) //-------ОТПРАВКА БИТА--------------------------------------------------------------------------------------------
{
  delayMicroseconds(Te);
  if (!b) digitalWrite(txPin, HIGH);
  delayMicroseconds(Te);
  digitalWrite(txPin, HIGH);
  delayMicroseconds(Te);
  digitalWrite(txPin, LOW);
}

void SendCame(long Code)  //-------ОТПРАВКА КОДА-------------------------------------------------------------------------------------------------
{
  for (int j = 0; j < 5; j++) // посылку посылаем как и брелок - 4 раза подряд.
  {
    digitalWrite(txPin, HIGH);
    delayMicroseconds(Te);
    digitalWrite(txPin, LOW); // посылаем стартовый импульс

    for (byte i = 12; i > 0; i--) {
      SendCameBit(bitRead(Code, i - 1)); // побитово перебираем и посылаем код
    }
    delay(16);
  }
  delay(2000); // сделать паузу после посылки на 2 с
}

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

СПАСИБО 

T.Rook
Offline
Зарегистрирован: 05.03.2016

Попробуйте вынести стороки с 151 по 196 (объявление функций transmission и receiving) в 132 строку ((за пределы loop, перед ним). И со "{" и "}" не запутайтесь!

alex0
Offline
Зарегистрирован: 14.12.2015

T.Rook пишет:

Попробуйте вынести стороки с 151 по 196 (объявление функций transmission и receiving) в 132 строку ((за пределы loop, перед ним). И со "{" и "}" не запутайтесь!

 

Помогло, спасибо, компилятор не ругается, но скетч всё равно не работает, на дисплее ничего не отображается((

T.Rook
Offline
Зарегистрирован: 05.03.2016

Ну хотя бы "loop" написал?

Если нет, ну чтож, надо смотреть, может быть ставить вывод отладочной инфы в сериал и думать!

alex0
Offline
Зарегистрирован: 14.12.2015

T.Rook пишет:

Ну хотя бы "loop" написал?

Если нет, ну чтож, надо смотреть, может быть ставить вывод отладочной инфы в сериал и думать!

 

Loop конечно написал, тем более там есть кусочек кода который на экран слово LOOP выводит, но даже оно не появляется((( Просто я плохо понимаю как работает тот код и от автора тоже никаких комментариев, поэтому скоро готов буду два МК ставить)))   А не знаешь, допустим есть два числа, 10101 и 1100, как получить из них 101011100 чтобы сохранить в EEPROM?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

C Ликсутовым бороться !??!?! Бесполезно ! Это такая мразь :) Неубиваемая !

Идите вы лучше в тему за деньги, раз такой .... никакой .

T.Rook
Offline
Зарегистрирован: 05.03.2016

alex0 пишет:

А не знаешь, допустим есть два числа, 10101 и 1100, как получить из них 101011100 чтобы сохранить в EEPROM?

Ну это сюда: https://www.arduino.cc/en/Reference/Bitshift

Два МК?? Да ладно! :)

alex0 пишет:

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

Немного терпения и все заработатет!