トランシーバーのプログラムです。

Dependencies:   mbed nRF24L01P

main44-3.cpp

Committer:
rgoto
Date:
2021-01-15
Revision:
1:dfc20a46ef43
Parent:
0:3b29eed48de4

File content as of revision 1:dfc20a46ef43:


//受信用と送信用を一つにする!ボタンで切り替え(元のプログラムは44で、44-2を貼り付ける)

#include "mbed.h"
#include "nRF24L01P.h"
RawSerial  pc(PA_2, PA_3,115200);
AnalogIn   mic_in(A0);
AnalogOut  sp_out(A2);
Ticker     interrput;

InterruptIn event(USER_BUTTON);  //送受信切り替え用ユーザーボタン

#define TRANSFER_SIZE   16
int      out_flg = 0;
int      rcv_flg = 0;
int      snd_flg = 0;
uint16_t txData[TRANSFER_SIZE*2];
int      txDataIdx = 0;
uint16_t rxData[TRANSFER_SIZE*2];
int      rxDataIdx = 0;
int      rxDataCnt = 0;
static uint16_t old = 0;
nRF24L01P my_nrf24l01p(D11, D12, D13, D10, D9,D8);    // mosi, miso, sck, csn, ce, irq
//nRF24L01P my_nrf24l01p(p5, p6, p7, p8, p9, p10);    // mosi, miso, sck, csn, ce, irq

DigitalIn button(USER_BUTTON, PullUp); //送受信切り替え(押してる間だけ送信、離すと受信)


void timer(){     /*タイマー割り込みによるSPEAKER out*/
   uint16_t ain;
   
    if(button == 1){
      
      if(rcv_flg) {
         out_flg=1;     
      } 
      if(out_flg){    
        sp_out.write_u16(rxData[rxDataIdx]);
        rxDataIdx++;
        if (rxDataIdx >= TRANSFER_SIZE*2) rxDataIdx=0;
      } 
    }   
  //タイマー割り込みによるMic in 16回ごとに送信
      
    if(button == 0){
      old = 0;
      if(1 /*out_flg*/){    
          ain= mic_in.read_u16();//_u16という表現で16ビットとして受信するようにする
          txData[txDataIdx] = ain;
          txDataIdx++;
        if (txDataIdx == TRANSFER_SIZE) {//最初の16回
               snd_flg = 1;
        } else if (txDataIdx >= TRANSFER_SIZE*2){//後の16回
               txDataIdx=0;
               snd_flg = 2;
          } 
      //  pc.printf("in %d\r\n",ain);
      //  sp_out.write_u16(ain);
        //out_flg = 0;              
         }
       }    
}
      
int main() {

  int bufferidx=0;
   int i=0;

    my_nrf24l01p.powerUp();
    my_nrf24l01p.setRfFrequency(NRF24L01P_MIN_RF_FREQUENCY);//2400-2525
    my_nrf24l01p.setRfOutputPower(NRF24L01P_TX_PWR_MINUS_12_DB);//mAX 0  -6 -12 -18
    my_nrf24l01p.setAirDataRate(NRF24L01P_DATARATE_1_MBPS);//250k,1000,2000K
    // Display the (default) setup of the nRF24L01+ chip
    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  my_nrf24l01p.getRfOutputPower() );
    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );

    pc.printf( "Type keys to test transfers:\r\n  (transfers are grouped into %d characters)\r\n", TRANSFER_SIZE );
    my_nrf24l01p.setTransferSize( TRANSFER_SIZE * sizeof( uint16_t ) );//mAX 32
    my_nrf24l01p.setReceiveMode();
    my_nrf24l01p.enable();
    
    wait_ms(100);
   // my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*)rxData,1);//dummy

    interrput.attach_us(&timer, 100);//100 usec 10Khz

 //   my_nrf24l01p.flush_rx_fifo();
 while(1){  //送受信をoenableで判断するため、それぞれのifを繰り返し見るためのwhile
    if (button == 1) {
        if(old == 0){  //このoldで、送信モードから受信に切り替わった時に一度だけリセットしたtxDataを送信する。これでもともとの受信側には変な音が残らない
          memset(txData,0,sizeof(txData)/*何バイト書き込むか*/);  //指定した場所のメモリをリセットする。
          wait_ms(10);
          my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char *)txData , TRANSFER_SIZE * sizeof(uint16_t) );
          wait_ms(10);
          my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*)(txData+TRANSFER_SIZE) , TRANSFER_SIZE * sizeof(uint16_t) );
          wait_ms(10);
          old = 1;
          }
        // If we've received anything in the nRF24L01+...
        if ( my_nrf24l01p.readable(NRF24L01P_PIPE_P0) ) {    //受信?
            // ...read the data into the receive buffer
            if (rxDataIdx < 16) bufferidx = TRANSFER_SIZE;   //最初に後半の配列を読み込ませようとすることで、入力と出力がぶつからずに交互に行える! 
            else bufferidx = 0;                              //後半の空の配列を読み込んでる間、スピーカも空の前半配列を出力。スピーカが後半(読み込んだ空のやつ)を出力中に前半(ここからデータあり)を読み込み、スピーカが前半(データあり)を出力中に・・・
            rxDataCnt = my_nrf24l01p.read( NRF24L01P_PIPE_P0, (char*)(rxData+bufferidx),TRANSFER_SIZE * sizeof( uint16_t ) );
            //myled1 = !myled1;
            //if (rcv_flg==0) 
            if ((i++ & 0xf/*16進数表示の15*/) ==0) pc.putc('.'); //16回に一回だけ()内の演算結果が0になるので、putcを実行する。
            rcv_flg = 1;                                       //普通にputcだと処理回数が多すぎてプログラムに負担がかかりすぎる。
        }
    }
    
     if (button == 0) {
         i++;
         if (snd_flg==1) {//最初のバッファ
               snd_flg=0;
               my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char *)txData , TRANSFER_SIZE * sizeof(uint16_t) );
              // pc.putc('1');
         }    
         else if (snd_flg==2)  {//後半のバッファ         
               snd_flg=0;
               my_nrf24l01p.write( NRF24L01P_PIPE_P0, (char*)(txData+TRANSFER_SIZE) , TRANSFER_SIZE * sizeof(uint16_t) );
             //    pc.putc('2');

         }
         
   }
 } //一番最初のwhileの}
}