Gen2-UHF-RFID-Reader学习(四)gate

本篇博客用于记录学习和使用github程序包Gen2-UHF-RFID-Reader的过程。出错的地方还望大家指正。
使用平台:ubuntu16.04      UHD3.14.0.HEAD-0-g6875d061     gnuradio3.7.10.1      USRP N210(SBX子板)
本篇分析gate_impl.cc文件。
Gate模块的作用:检测reader发出的命令,消除原始数据中的直流分量,并将结果输出到decoder模块中。
消除直流分量的原因:系统中信号的直流分量是由硬件等其他因素引起的,不携带我们所需要的信息,消除直流分量可在保证信息准确性的前提下减少系统处理数据的负担。

    gate::sptr
    gate::make(int sample_rate)
    {
      return gnuradio::get_initial_sptr
        (new gate_impl(sample_rate));
    }

gate模块需通过采样率sample_rate进行初始化。

    /*
     * The private constructor
     */
    gate_impl::gate_impl(int sample_rate)
      : gr::block("gate",
              gr::io_signature::make(1, 1, sizeof(gr_complex)),   //输入端口
              gr::io_signature::make(1, 1, sizeof(gr_complex))),  //输出端口
              n_samples(0), win_index(0), dc_index(0), num_pulses(0), signal_state(NEG_EDGE), avg_ampl(0), dc_est(0,0)  //默认参数,用于计数或变换
    {

       n_samples_T1       = T1_D       * (sample_rate / pow(10,6));  //T1时间内的采样点数
       n_samples_PW       = PW_D       * (sample_rate / pow(10,6));  //Tari/2时间内的采样点数
        n_samples_TAG_BIT = TAG_BIT_D * (sample_rate / pow(10,6));  //1bit数据的采样点数
      
      win_length = WIN_SIZE_D * (sample_rate/ pow(10,6)); //win窗口下采样点数
      dc_length  = DC_SIZE_D  * (sample_rate / pow(10,6)); //直流分量的采样点数

      win_samples.resize(win_length); //按照长度分配内存
      dc_samples.resize(dc_length);

      GR_LOG_INFO(d_logger, "T1 samples : " << n_samples_T1);
      GR_LOG_INFO(d_logger, "PW samples : " << n_samples_PW);

      GR_LOG_INFO(d_logger, "Samples of Tag bit : "<< n_samples_TAG_BIT);
      GR_LOG_INFO(d_logger, "Size of window : " << win_length);
      GR_LOG_INFO(d_logger, "Size of window for dc offset estimation : " << dc_length);
      GR_LOG_INFO(d_logger, "Duration of window for dc offset estimation : " << DC_SIZE_D << " us");

      
      // First block to be scheduled
      GR_LOG_INFO(d_logger, "Initializing reader state...");
      initialize_reader_state();  //实例化模块时先进行reader初始化
    } 

构造函数:一个complex输入端口,一个complex输出端口;进行采样点数量的计算,方便后续程序使用。

    /*
     * Our virtual destructor.
     */
    gate_impl::~gate_impl()
    {
    }
    void
    gate_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
    {
        ninput_items_required[0] = noutput_items;
    }

析构函数没有内容。forecast函数为自带函数,无需变更。

int
    gate_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {

      const gr_complex *in = (const gr_complex *) input_items[0]; //输入
      gr_complex *out = (gr_complex *) output_items[0]; //输出

      int n_items = ninput_items[0];
      int number_samples_consumed = n_items; //使用过的采样点数量
      float sample_ampl = 0; //采样点幅值
      int written = 0; //下标,用于输出数据流的写入

      
      if( (reader_state-> reader_stats.n_queries_sent   > MAX_NUM_QUERIES ||
           reader_state-> reader_stats.tag_reads.size() > NUMBER_UNIQUE_TAGS) &&  
           reader_state-> status != TERMINATED) //达到终止条件
      {
        reader_state-> status = TERMINATED;  //系统中止
        gettimeofday (&reader_state-> reader_stats.end, NULL); //计时结束
        std::cout << "| Execution time : " << reader_state-> reader_stats.end.tv_sec - reader_state-> reader_stats.start.tv_sec << " seconds" << std::endl;
        GR_LOG_INFO(d_logger, "Termination");
       }

      // Gate block is controlled by the Gen2 Logic block
      if(reader_state->gate_status == GATE_SEEK_EPC)  //gate状态为seek_epc
      {
        reader_state->gate_status = GATE_CLOSED; //更改状态
        reader_state->n_samples_to_ungate = (EPC_BITS + TAG_PREAMBLE_BITS) * n_samples_TAG_BIT + 2*n_samples_TAG_BIT; //需要解码的数据量为(EPC_BITS + TAG_PREAMBLE_BITS+2)位
        n_samples = 0; //采样点数归0
      }
      else if (reader_state->gate_status == GATE_SEEK_RN16)
      {
        reader_state->gate_status = GATE_CLOSED; //更改状态
        reader_state->n_samples_to_ungate = (RN16_BITS + TAG_PREAMBLE_BITS) * n_samples_TAG_BIT + 2*n_samples_TAG_BIT; //需要解码的数据量为(RN16_BITS + TAG_PREAMBLE_BITS+2)位
        n_samples = 0; //采样点数归0
      }
      
      if (reader_state->status == RUNNING)
      {
        for(int i = 0; i < n_items; i++)                            
        {
          // Tracking average amplitude 
          //追踪窗口内的平均幅值
          sample_ampl = std::abs(in[i]);
          avg_ampl = avg_ampl + (sample_ampl - win_samples[win_index])/win_length;  
          win_samples[win_index] = sample_ampl; 
          win_index = (win_index + 1) % win_length;
  
          //Threshold for detecting negative/positive edges
          sample_thresh = avg_ampl * THRESH_FRACTION;  //判别上升沿或下降沿的阈值

          if( !(reader_state->gate_status == GATE_OPEN) )
          {
            //Tracking DC offset (only during T1)
            //预测直流分量幅值
            dc_est =  dc_est + (in[i] - dc_samples[dc_index])/std::complex<float>(dc_length,0);  
            dc_samples[dc_index] = in[i]; 
            dc_index = (dc_index + 1) % dc_length;
          
            n_samples++;

            // Potitive edge -> Negative edge,采样点数归0
            if( sample_ampl < sample_thresh && signal_state == POS_EDGE)
            {
              n_samples = 0;
              signal_state = NEG_EDGE;
            }
            // Negative edge -> Positive edge 
            else if (sample_ampl > sample_thresh && signal_state == NEG_EDGE)
            {
              signal_state = POS_EDGE;
              if (n_samples > n_samples_PW/2)  //脉冲数+1,用于判断是否达到检测命令的脉冲
                num_pulses++; 
              else
                num_pulses = 0; 
              n_samples = 0;
            }

            if(n_samples > n_samples_T1 && signal_state == POS_EDGE && num_pulses > NUM_PULSES_COMMAND) //开始检测命令
            {
              GR_LOG_INFO(d_debug_logger, "READER COMMAND DETECTED");

              reader_state->gate_status = GATE_OPEN;

              reader_state->magn_squared_samples.resize(0);


              reader_state->magn_squared_samples.push_back(std::norm(in[i] - dc_est));
              out[written] = in[i] - dc_est;   //输出=输入减去直流分量
              written++;

              num_pulses = 0; 
              n_samples =  1; // Count number of samples passed to the next block

            }
          }
          else
          {
            n_samples++;

            reader_state->magn_squared_samples.push_back(std::norm(in[i] - dc_est));
            out[written] = in[i] - dc_est; // Remove offset from complex samples           
            written++;
            if (n_samples >= reader_state->n_samples_to_ungate)
            {
              reader_state->gate_status = GATE_CLOSED;    
              number_samples_consumed = i+1;
              break;
            }
          }
        }
      }
      consume_each (number_samples_consumed);
      return written;
    }

模块的核心工作,其逻辑可用下述流程图表示
在这里插入图片描述
!这部分代码只看懂了大致意思,为什么这么写还没有完全明白,等清楚之后再来更新。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EPC Class-1 Gen2 UHF RFID V2.0.1 协议是一种用于无线射频识别(RFID)技术的标准。该协议是由电子产品代码(EPC)全球标准化组织制定的,并用于标签和阅读器之间进行通信。 该协议的第一个版本于2005年发布,V2.0.1 是在此基础上进行改进和升级的最新版本。以下是该协议的一些主要特点: 1. 频段:该协议使用超高频(UHF)频段来进行通信,通常在860-960 MHz 的频率范围内操作。这一频段具有较长的传输距离和高吞吐量,使其适用于许多应用场景。 2. 标签和阅读器:该协议支持EPC Class-1 Gen2 标签与阅读器之间的双向通信。标签是被动式的,只有在接收到读写器的信号时才能进行通信和工作。 3. 协议格式:协议的通信格式采用一种称为“质询-响应”(Query-Response)的方式。读写器发送一个质询命令给标签,标签收到命令后进行特定操作,并将响应消息返回给读写器。 4. 数据传输:该协议使用一种称为“电场脉冲调制”(Electromagnetic pulse modulation)的调制技术来传输数据。这种技术可有效地传输数据并提高通信的可靠性。 5. 安全性:协议提供了一些安全机制,如加密和认证,以确保通信的安全性和数据的保密性。 6. 应用领域:EPC Class-1 Gen2 UHF RFID V2.0.1 协议在物流和供应链管理、库存管理、资产追踪等领域有广泛的应用。它可以帮助提高物流效率、实现自动化管理,并提供实时的数据监测和跟踪。 总之,EPC Class-1 Gen2 UHF RFID V2.0.1 协议是一种基于超高频的RFID技术标准,具有高效、安全和可靠的特点,广泛应用于物流和供应链管理等领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值