UMEHOSHI ITA TOP PAGE    COMPUTER SHIEN LAB

[UMEHOSHI ITA]の制御で使っているIC「PIC32MX270F256B-I/SO」のフラッシュメモリには、テスト用プログラムが書き込まれいています。
これを利用したユーザー用のプログラムを「ウメ・エディットプログラム」と呼ぶことにします。
「ウメ・エディットプログラム」の開発では「umehoshiEditツール」が必要で、 その取得や最初の操作情報は、こちらを参照してください。

USBでなく、「AE-RN-42-XB 」のBluetoothモージュールを介して録音する検討

「テスト・ウメ・フラッシュ」の起動には、UART1コマンドモードと呼ぶ機能があり、その状態ではUSBの代わりにUART1経由でプログラムを送ったり、指定絶対番地の関数呼び出しが可能となります。
このUART1コマンドモードで起動するには、パワーオンの状態でSW1とSW2を押して、 SW1を離してから4秒以上後にSW2を離します。
「AE-RN-42-XB 」のBluetoothモージュールなどを付けると そのシリアルラインがUART1に繋がっているので、それを利用するとBluetooth経由で プログラムを送って起動する芸当ができます。
このページではこの能力を利用して、左のように電池駆動の状態で、離れたPCなどからBluetoothを介し、 8KHzモノラルの録音を行わせるプログラムを送って実行するpython例を紹介します。

コンデンサマイクはCN8(AN0)に直付けしています。
取付参考ページ

Bluetoothのペアリングは、このページで紹介しています。


実行中は、30mA〜100mA程度の電流が流れます。(実測値)

[UMEHOSHI ITA]側のADC結果をBluetoothで出力するプログラム

この別ページでADCデフォルトプログラムを書き換えて使う例を示しています。
この上記リンクで示したコードではADCの出力がUSBになっていますが、この出力をUART1に変更したプログラムを下記で示しています。
出力をUART1に変更することで、UART1が接続されるBluetoothモジュールを介して、無線でデータが送出されます。
(ADCの出力をUSBからUART1へ変更する際に変更した箇所は、下記ソースに★マークのコメントを付けました。)
なお、ADCの基本的な使い方はこちらの別ページで示していますが、以下で主要な点を列挙します。

#include <xc.h> // ADC_8K_AN0_BT.c  8KHx AN0 2block 
#include "common.h"

#define MY_ADC_ERR_OVERFLOW  0x0001 // ADC取得データの送信が間に合わなないエラー

#define AdrStart	0x80005000
__attribute__((address( AdrStart  ))) void start (void);

#define AdrStop	0x80006000
__attribute__((address( AdrStop))) void stop (void);

void adc_umeFunc1_1(struct ADC_BUFF *p_buff);//自前のADC割り込みルーチン
void adc_usb_out(struct ADC_BUFF *p_buff);//自前のUART1に出力するTimer3の割り込みルーチン

void start()
{
    _RB15 = ! _RB15 ;// LEDの点灯を反転
    _HANDLES[_IDX_ADC_1_FUNC]=  (void *)adc_umeFunc1_1;//ADCの割り込み(バッファに記憶)を自作の処理に置き換える
    _HANDLES[_IDX_TIMER_3_FUNC] = (void *)adc_usb_out;//Timer3割り込み(バッファの出力)を自作の処理に置き換える

    _set_adc_mode(1,0); // チャンネル指定と、bin/textの選択で、ADCのバイナリ出力指定
    _set_adc_exe(2 , 1);// ブロックのサンプリングを繰り返し数とループフラグ指定

    T3CONbits.ON = 0; // timer3停止
    AD1CON2bits.ALTS = 0; // MUX AおよびMUX B入力マルチプレクサ設定を交互に使わない
    AD1CON2bits.SMPI = 0; // 割り込みあたりサンプリング(1 チャンネルモードを指定)
    AD1CHSbits.CH0SA = 0; // MUX A チャンネル 0 の正極性入力に AN0 を選択する
    AD1CHSbits.CH0SB = 1; // MUX B チャンネル 0 の正極性入力に AN1 を選択する
    PR3=4999; // 8KHzサンプリン用設定値:(1/8e3)/(1/40e6)-1 = 4999

    T3CONbits.ON = 1; // timer3停止
}

void stop()
{
    _set_adc_exe(2 , 0);// 現ブロック送信で終了
}

// ADCの新しい割り込み処理
void adc_umeFunc1_1(struct ADC_BUFF *p_buff) {
    static int no_send_count = 0; // 送信できない場合のデクリメント
    static uint16_t valAN0, valAN1;

    // 割り込み中で、下記バッファを必ず操作しなければならない。
    // (そうしないと、割込みが永続(persistent)のため、連続発生の不具合が生じる。)
    // バッファへの格納先を確認(ビットチェック格納先を判定)
    int idx = (AD1CON2 & _AD1CON2_BUFS_MASK) != 0;
    if (idx) {//1:ADC はバッファ0x8〜0xF に書き込み中(ユーザは0x0〜0x7 にアクセス可能)
        valAN0 = ADC1BUF0; //MUX A のAD変換値
    } else { //0: ADC はバッファ0x0〜0x7 に書き込み中(ユーザは0x8〜0xF にアクセス可能)   
        valAN0 = ADC1BUF8; //MUX A のAD変換値
    }

    if (p_buff->index_adc_sample >= ADC_BUFF_SIZE) {
        if (p_buff->index_adc_out_block != ADC_OUT_NONE) {
            // エラーのサンプリング停止(メモリオーバー UART1出力が間に合わない).
            no_send_count--;
            goto end_proc; // 下記のサンプリングをしない
        }
        // オルタネイト・バッファブが一杯なので、切り替える 
        p_buff->index_adc_sample = 0;
        int next_index_block_sample = p_buff->index_adc_block_sample;
        next_index_block_sample++;
        if (next_index_block_sample == 2) {
            next_index_block_sample = 0;
        }
        p_buff->index_adc_out_block = p_buff->index_adc_block_sample;
        p_buff->index_adc_block_sample = next_index_block_sample;
    }

    if (no_send_count != 0) {// UART1出力が間に合わないくて、出力されなかったデータ数?
        // valAN0 = valAN1 = no_send_count; //出力できなかった数を(負の数)セット この実行が頻繁に起きるのでコメント化【A】
        no_send_count = 0;
    }
    p_buff->adc_buffer0[p_buff->index_adc_block_sample][p_buff->index_adc_sample] = valAN0;
    p_buff->index_adc_sample++;

end_proc:
    IFS0CLR = _IFS0_AD1IF_MASK; // Clear ADC interrupt flag  
}

int my_adc_set_err = 0;

char hex[5]={0};// 文字列変換用
void set_hex_string(uint16_t d, char s[]) {
    int i;
    for (i = 3; i >= 0; i--) {
        char c = (char) (d & 0x0f);
        c = c >= 10 ? c - 10 + 'A' : c + '0';
        s[i] = c;
        d >>= 4;
    }
    s[4] = '\x0';
}

// Timer3の新しい割り込み処理
void adc_usb_out(struct ADC_BUFF *p_buff) {
    static int flag_start_ADC = 1;
    static int flag_end_ADC = 0;
    static int i, idx_block, i_pos;
    static int16_t data;

    static int tim3_skip_count=0;// timer3が早すぎる場合の送出調整用★
    static int skip_timing =0;//★
    skip_timing = PR3;

    if( skip_timing < 100) { // 1つのサンプル周期が約400KHz以上?★
        skip_timing = 100 - skip_timing;
        tim3_skip_count++;
        if(tim3_skip_count < skip_timing ) {
            IFS0CLR = _IFS0_T3IF_MASK; // 次の割り込みを可能にする
            return;
        }
        tim3_skip_count =0;
     }//★

    struct ADC_CTRL *p_ctrl = p_buff->p_ctrl;

    if (p_buff->index_adc_out_block == ADC_OUT_NONE) {// UART1送信するデータがない? 
        IFS0CLR = _IFS0_T3IF_MASK; // Clear the timer interrupt status flag
        return;
    }
    int size = _get_uart1_capacity(); // ★★
    if (size < 50) {
        IFS0CLR = _IFS0_T3IF_MASK; // Clear the timer interrupt status flag
        return; //出力バッファに余裕がないので、次の呼び出しにする。  
    }
    if (_request_acc_outbuff(_ID_ACCESS_UARTASK) == 0) {
        IFS0CLR = _IFS0_T3IF_MASK; // Clear the timer interrupt status flag
        return;   //UART1出力権限取得失敗で、、次の呼び出しにする。
    }

    // ADC DATA 送出.============>UART1
    int text_mode = p_ctrl->adc_out_usb == (void (*)()) _HANDLES[_IDX_API_SEND_HEX_LOW]; 
    if (flag_start_ADC) {// ----------送出ブロック開始----------------
        p_buff->adc_buff_data_numb = ADC_BUFF_SIZE;
        ((void (*)(struct ADC_BUFF*))_UME_ENCODE_ADC_BUFF)(p_buff);

        _send_string_to_uart1("\r\nADC_START1\r\n");//★★
        //if (text_mode == 1)_send_uart1('T'); //コメントに変更してバイナリ送信専用にしている//★★

        set_hex_string(p_ctrl->count_end_ADC, hex);// hexへ文字列変換★★
        _send_string_to_uart1(hex); //送信データ数★★
        _send_string_to_uart1("\r\n");//★★

        //usb_receiver_disable_flag = 1; //UART1受信不可
        flag_start_ADC = 0; //開始処理を終えた〇
        flag_end_ADC = 0;

    } else if (p_ctrl->counter_ADC >= p_ctrl->count_end_ADC) {
        // ----------送出ブロック終了の処理------
        if (!flag_end_ADC) {
            flag_end_ADC = 0;
            flag_start_ADC = 1;
            _send_string_to_uart1("ADC_END\r\n");//★★
            if (p_ctrl->set_sequence_flag) {// set_ADCの登録がある時
                p_ctrl->set_sequence_flag = 0;
                if (p_ctrl->block_size_ADC != 0) {// 継続データ指示がある ?
                    // 目標サンプル数 設定があればセット
                    p_ctrl->count_end_ADC = p_buff->adc_buff_data_numb * p_ctrl->block_size_ADC;
                    if (p_ctrl->out_channel_bits == 0x3) {
                        p_ctrl->count_end_ADC <<= 1;  //AN0,AN1 の2つ分
                    }
                } else {
                    T3CONbits.ON = 0; // timer3停止
                    p_buff->index_adc_out_block = ADC_OUT_NONE;
                }
            }
            if (!p_ctrl->loop_flag_ADC) {//ループしない?
                T3CONbits.ON = 0; // timer3割込みオフ.
                p_ctrl->block_size_ADC = 0;
                p_buff->index_adc_out_block = ADC_OUT_NONE;
            }
            p_ctrl->counter_ADC = 0;
        }

    } else {// ------------- ADC データブロック送出中 -------------------------
        for (i = 0; i < 2; i++) {// ADCの値の1ワードを2つ分送出する。
            idx_block = p_buff->index_adc_out_block;
            i_pos = p_buff->index_adc_out_pos;

            data = p_buff->adc_buffer0[idx_block][i_pos]; //出力対象
            //data = p_buff->adc_buffer1[idx_block][i_pos]; //出力対象
            //if (data < 0) my_adc_set_err=MY_ADC_ERR_OVERFLOW;

            // p_ctrl->adc_out_usb(data);
            //set_hex_string(data, hex);// hexへ文字列変換★★
            //_send_string_to_uart1(hex); //送信データ数★★
		_send_uart1(data & 0x0ff); //バイナリMode//★★
		_send_uart1(data >> 8); //バイナリMode//★★

            p_ctrl->counter_ADC++;

            ++p_buff->index_adc_out_pos;
            //if (p_ctrl->counter_ADC % 16 == 0 && text_mode == 1) {
                // TEXT MODE 出力の場合だけ出力(バイナリ時は出力しない)
            //    _send_string_to_uart1("\r\n");// ★★
            //}
            if (p_buff->index_adc_out_pos >= p_buff->adc_buff_data_numb) {
                p_buff->index_adc_out_pos = 0;
                p_buff->index_adc_out_block = ADC_OUT_NONE; // CHUNKブロックのUART1出力終了.
            }
        }
    }
    _release_acc_outbuff(_ID_ACCESS_UARTASK);
    IFS0CLR = _IFS0_T3IF_MASK; // Clear the timer interrupt status flag
}

上記をビルドしたコードを貼り付けた次のPythonコードで、Bluetoothを選択し、 プログラムを転送して実行させます。
なお、bluetooth(UART1)への出力イメージを下記に示します。

ADC_START1
0800
・・0x0800ワードのバイナリ・・
ADC_END
ADC_START1
0800
・・0x0800ワードのバイナリ・・
ADC_END

上記は、2つのブロックを表示していますが、これがEnetr入力があるか、エラーになるまで繰り返されます。
この一つのブロックが、ADCの記憶バッファ(p_buff->adc_bufferの[0]または[1])のサイズで、4096バイトです。この情報が、
・・0x0800ワードのバイナリ・・の部分です。
次に示すpythonのbluetooth受信プログラム「receiveBt(code)関数」では、
"ADC_START1\r\n"直後の"0800\r\n"のサイズより、 バイナリのサイズを判断して、それで「test.wav」のファイルを作っています。

PC側の遠隔操作用Pythonプログラム

上記プログラム転送・実行と、それで送られるblutoothの録音情報でファイル「test.wav」化するpythonのプログラムです。
(これはこの別ページで示したBluetoothのPythonプログラムを、 変更したコードです。)
上記をビルドして得られたHexコードの文字列をBluetoothを介して転送して、Bluetoothを介して実行させるように作っています。
USBは電源供給だけに使って、遠隔的にプログラム転送と開始を行う例です。
また、 ●●●● の箇所がキー入力操作の部分です。 )

import sys         # btc_ADC_8K_AN0.py
import time
import threading
from time import sleep

SamplingRate = 8000 # 8KHz
flag_playing = True # 再生フラグ
path="test.wav"

''' barray の16bitリトルエンディアンバイト列から、未圧縮でpathのサウンドファイルを作る'''
import wave
wavefile = wave.open(path, 'wb') # waveファイルをバイナリ保存用として開く。
wavefile.setnchannels(1) # モノラル(単一の音信号)
wavefile.setsampwidth(2) # 2byteのデータ群と録音する指定
wavefile.setframerate(SamplingRate) # サンプリングレート

import bluetooth # https://pybluez.readthedocs.io/en/latest/install.html

devices = bluetooth.discover_devices(lookup_names=True)
print("Found {} devices.".format(len(devices)))

n=0
for addr, name in devices: # ペアリングデバイスリストアップ
    print("No={}  {} - {}".format(n, addr, name))
    n+=1

no=input("Bluetooth Device No=>>") # bluetoothデバイスを選択 # ●●●●●

addr, name = devices[int(no)] # 上記選択デバイスをメモ
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) # ソケット生成
uuid = '00001101-0000-1000-8000-00805F9B34FB' # SPP (シリアルポートプロファイル) の UUID
service = []
retry = 1
while len(service) == 0: # 接続予定のデバイスのサービスが存在するか?のチェックで、見つかるまで繰り返す。
     print( "Looking for service on {0}, try {1}".format(addr, retry) )
     service = bluetooth.find_service(address=addr, uuid=uuid)
     retry = retry + 1
     time.sleep(1)

if len(service) != 1:
    print("not find service.")
    sys.exit(1)

# print(service)
service = service[0]
for k in service: # 見つかったデバイス情報を表示
    print("\t", k, ":" , service[k])

print( "Service found. Name={0}".format(service["name"]) )
print( "Connecting to service." )
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
try:
   sock.connect((addr, service["port"])) # 接続!!
   print( "Connected to service on {0} on port {1}".format(addr, service["port"]) )
except bluetooth.btcommon.BluetoothError as e:
   print( "Connection failed: {0}".format(e) )
   exit(0)

strLine=""
nn=0
flag_ADC_START=False
def  receiveBt(code): # bluetooth接続後の1byte受信 -----------------------------------------------
    global strLine,flag_ADC_START,nn
    strLine+=chr(code)
    if code == 0x0a:
        print( strLine , end ="")
        if flag_ADC_START==False and "ADC_START" in strLine:
            flag_ADC_START=True
        elif flag_ADC_START==True:
            size= int(strLine,16)*2 # 16進サイズ文字列よりサイズ取得
            total = 0
            while(size > 0):
                bin=sock.recv(size) # binaryで1byte入力
                wavefile.writeframes( bin ) # USB受信データを加工しないで、wavファイル化
                n=len(bin)
                total += n
                size -= n
                print( "Bluetooth 受信byte:", n, "total=", total, size)
            flag_ADC_START=False
            nn+=1
            #if nn == 3: sys.exit()
        strLine = ""

loop_flag=True
def read_loop(): # 受信スレッド用の関数 ------------------------------------------------------------
    global loop_flag
    while loop_flag:
        try:
            b=sock.recv(1) # binaryで1byte入力
            #print(type(b), b)
            #print( chr(b[0]), end=" ") # 文字に変換して表示
            receiveBt( b[0])
        except Exception as e:
           print("End Thread Exception:" , e) 
           loop_flag = False
           return

# スレッドに read_loop 関数を渡す
t_id = threading.Thread(target=read_loop)
t_id.start() # スレッドスタート
input("受信スレッド開始! Enterでプログラム送信と実行>>") # ●●●●●

hexCmd='''S04800080000000000000D9
S04800080040000000000D5
S048000800C0000000000C6
S04800080100000000000D8
S04800080140000000000D4
S04800080180000000000D0
S048000801C0000000000C5
S04800080200000000000D7
S04800080240000000000D3
S04800080280000000000CF
S048000802C0000000000C4
S04800080300001000000D5
S108000500000E8FFBD271400BFAF1000BEAF21F0A00317
S10800050100088BF023C2061428C008042300100422CB7
S108000502000FF00443088BF033C20616294C47B827C63
S108000503000206162A400A0023C804042340080033CD3
S10800050400020516324000043AC00A0023C78404234D0
S1080005050000080033C60536324000043AC00A0023CC8
S108000506000644242340000428C010004242128000003
S10800050700009F840000000000000A0023C60424234EB
S1080005080000000428C020004240100052409F84000F3
S1080005090000000000080BF033C000A6294C47B027C9B
S10800050A000000A62A481BF033C109062940400027C97
S10800050B000109062A481BF033C109062948428027C8B
S10800050C000109062A481BF033C4090628C049C027C6F
S10800050D000409062AC81BF033C4090628C010004248D
S10800050E00004DE827C409062AC80BF023C871303245C
S10800050F000200A43AC80BF033C000A62940100042491
S108000510000C47B827C000A62A421E8C0031400BF8F5B
S1080005110001000BE8F1800BD270800E00300000000BF
S108000600000E8FFBD271400BFAF1000BEAF21F0A00316
S10800060100000A0023C604242340000428C02000424EE
S1080006020002128000009F840000000000021E8C003EE
S1080006030001400BF8F1000BE8F1800BD270800E00372
S04800060400000000000D7
S108000512000F0FFBD270C00BEAF21F0A0031000C4AF1E
S10800051300081BF023C1090428C800042302B100200BF
S108000514000FF0042300400C2AF0400C28F08004010A1
S1080005150000000000081BF023C7090428CFFFF43307D
S1080005160000180023C0A8043A46114000800000000EE
S10800051700081BF023CF090428CFFFF43300180023C4B
S1080005180000A8043A41000C28F0420428C00044228B2
S088000519000210040140000000042
S1080005198001000C28F0820438C0200022408006210D2
S10800051A800000000000180023C0C80428CFFFF432483
S10800051B8000180023C0C8043AC9D14000800000000B3
S10800051C8001000C28F042040AC1000C28F0020428C8A
S10800051D8000000C2AF0000C28F010042240000C2AF8A
S10800051E8000000C38F020002240200621400000000F4
S10800051F8000000C0AF1000C28F0020438C1000C28F7A
S108000520800082043AC1000C28F0000C38F002043AC8B
S1080005218000180023C0C80428C0300401000000000EF
S1080005228000180023C0C8040AC1000C28F0020458C95
S1080005238001000C28F0420428C0180033C0A806394A6
S1080005248001000C48F802A05002110A20040100200DD
S10800052580021108200000043A41000C28F0420428CCB
S0C8000526800010043241000C28F042043AC4A
S10800052740088BF023C0010033C341043AC21E8C0037F
S1080005284000C00BE8F1000BD270800E00300000000A9
S108000529400F0FFBD270C00BEAF21F0A0032110800045
S10800052A4001400C5AF1000C2A7030002240000C2AF8F
S08800052B400CD140008000000000C
S10800052BC001000C2972014027C0F0042300400C2A3A3
S10800052CC000400C2830A0042280700401400000000E2
S10800052DC000400C29337004224FF0042302014027CA3
S10800052EC00C1140008000000000400C29330004224E0
S10800052FC00FF0042302014027C0400C2A30000C28F7C
S108000530C001400C38F211062000400C393000043A0C6
S0C8000531C001000C297021102001000C2A75C
S1080005328000000C28FFFFF42240000C2AF0000C28F4C
S108000533800E0FF4104000000001400C28F04004224BF
S108000534800000040A021E8C0030C00BE8F1000BD277D
S0880005358000800E0030000000028
S108000536000D8FFBD272400BFAF2000BEAF21F0A0030D
S1080005370002800C4AF80BF023C200A428C2118400081
S1080005380000180023C148043AC0180023C1480428CAC
S108000539000640042281A004010000000000180023C01
S10800053A0001480428C64000324231862000180023CD3
S10800053B000148043AC0180023C1880428C01004324B1
S10800053C0000180023C188043AC0180023C1880438C98
S10800053D0000180023C1480428C2A10620006004010D2
S10800053E0000000000088BF023C00400324341043ACB7
S10800053F00005160008000000000180023C188040ACD8
S1080005400002800C28F1420428C1000C2AF2800C28F7C
S1080005410000820438C02000224060062140000000011
S10800054200088BF023C00400324341043AC05160008B5
S1080005430000000000000A0023CA44242340000428CE6
S10800054400009F84000000000001400C2AF1400C28FB3
S10800054500032004228060040100000000088BF023CE6
S10800054600000400324341043AC051600080000000001
S10800054700000A0023C944142340000428C00200424DF
S10800054800009F8400000000000060040140000000019
S10800054900088BF023C00400324341043AC05160008AE
S10800054A000000000001000C28F1800438C00A0023CC2
S10800054B000A84142340000428C261062000100422CD0
S10800054C000FF0042301800C2AF0180023C3080428C81
S10800054D0002D004010000000002800C28F00040324E2
S10800054E000102043AC00A0023C5C4242340000428CA3
S10800054F0002800C48F09F840000000000000A0023CB2
S108000550000A84242340000428C0080033C2C586424BA
S10800055100009F84000000000001000C28F0400428CD5
S108000552000FFFF4230212040000180023C04804524B2
S108000553000A514000C0000000000A0023CA8424234D4
S1080005540000000428C0180033C0480642409F84000CC
S1080005550000000000000A0023CA84242340000428CDF
S1080005560000080033C3C58642409F8400000000000D5
S1080005570000180023C308040AC0180023C1C8040AC9A
S108000558000FC150008000000001000C28F0000438CC5
S1080005590001000C28F0400428C2B10620047004014C7
S10800055A000000000000180023C1C80428C90004014D9
S10800055B000000000000180023C1C8040AC0180023CC2
S10800055C00001000324308043AC00A0023CA8424234B2
S10800055D0000000428C0080033C4058642409F84000B8
S10800055E000000000001000C28F1000428C22004010E6
S10800055F000000000001000C28F100040AC1000C28FB3
S1080005600000C00428C15004010000000002800C28FDD
S1080005610001020438C1000C28F0C00428C18006200BA
S108000562000121800001000C28F040043AC1000C28FB4
S1080005630001400438C030002240F0062140000000001
S1080005640001000C28F0400428C401802001000C28FB9
S108000565000040043AC9E1500080000000080BF033CB0
S108000566000000A6294C47B027C000A62A42800C28F76
S10800056700002000324082043AC1000C28F0800428CB5
S1080005680000A0040140000000080BF033C000A6294C8
S108000569000C47B027C000A62A41000C28F0C0040AC67
S10800056A0002800C28F02000324082043AC1000C28F97
S10800056B000000040ACFC150008000000000180023CC7
S10800056C000208040ACF7150008000000002800C28FAC
S10800056D0000820438C0180023C248043AC2800C28F82
S10800056E0000C20438C0180023C288043AC0180023C8E
S10800056F0002480448C0180023C2880428C2800C38F80
S1080005700008022040021108200401002002110620027
S10800057100000004294201E027C0180023C2C8043A4B6
S10800057200000A0023CA04242340000428C0180033CC6
S1080005730002C806384FF0063302120600009F84000B5
S1080005740000000000000A0023CA04242340000428CE6
S1080005750000180033C2C806384031A0300201E037CB2
S108000576000FF0063302120600009F8400000000000E4
S1080005770001000C28F0000428C010043241000C28FBA
S108000578000000043AC2800C28F0C20428C01004324A4
S1080005790002800C28F0C2043AC2800C28F0C20438C5E
S10800057A0002800C28F1020428C2A10620006004014BB
S10800057B000000000002800C28F0C2040AC2800C28F8F
S10800057C00002000324082043AC0180023C2080428CB9
S10800057D000010043240180023C208043AC0180023CBF
S10800057E0002080428C02004228B8FF401400000000B7
S10800057F00000A0023C984142340000428C00200424C9
S10800058000009F840000000000088BF023C00400324CF
S108000581000341043AC21E8C0032400BF8F2000BE8F5A
S0C80005820002800BD270800E003000000006A
S108000582C000D0A4144435F5354415254310D0A00009F
S048000583C000D0A000099
S0C80005840004144435F454E440D0A00000043
S108000584C003080008004000000010000000100000027
S088000585C00008000803000000025
R00800050000061
'''

# コマンドを送信---------------------
for s in hexCmd.split("\n"):
    s += "\r\n"
    #print(s, end="")
    sock.send(s.encode('ascii')) # byteに変換して送信
    sleep(0.05)

while True: # 送信用のループ
    s = input("Enterで終了>") # 送信文字列のキー入力 # ●●●●●  
    if s == "": break # Enterだけすると、終了
    #s += "\r\n"
    #sock.send(s.encode('ascii')) # byteに変換して送信

sock.close()
wavefile.close()
次に実行例の一部を示します。
SW1とSW2を押してSW1を離すと、点灯後に3秒後に消灯します。その後で点灯しますがこのタイミングでSW2を離して UART1コマンドモードにしてから行ってください。
R:\adc_work>python btc_ADC_8K_AN0.py
Found 3 devices.
No=0  20:17:DB:21:F9:81 - SBT-D2
No=1  AC:F5:5F:79:15:35 - DC-0531
No=2  00:06:66:7D:BE:FE - RNBT-BEFE
Device No=>>2
Looking for service on 00:06:66:7D:BE:FE, try 1
         host : 00:06:66:7D:BE:FE
         name : b'RNI-SPP'
         description :
         port : 1
         protocol : RFCOMM
         rawrecord : b'6\x00;\t\x00\x00\n\x00\x01\x00\x02\t\x00\x015\x03\x19\x11\x01\t\x00\x045\x0c5\x03\x19\x01\x005\x05\x19\x00\x03\x08\x01\t\x00\x065\t\ten\t\x00j\t\x01\x00\t\x01\x00%\x07RNI-SPP'
         service-classes : [b'1101']
         profiles : []
         provider : None
         service-id : None
         handle : 65538
Service found. Name=b'RNI-SPP'
Connecting to service.
Connected to service on 00:06:66:7D:BE:FE on port 1
受信スレッド開始! Enterでプログラム送信と実行>>
S04800080000000000000D9
SET:80008000
S04800080040000000000D5
・・・省略・・・・
S108000584C003080008004000000010000000100000027
SET:8000584C
S088000585C00008000803000000025
SET:8000585C

R00800050000061
START:80005000

コマンドの送信が終了
Enterで終了>
ADC_START1
0800
Bluetooth 受信byte: 110 total= 110 3986
Bluetooth 受信byte: 66 total= 176 3920
Bluetooth 受信byte: 125 total= 301 3795
Bluetooth 受信byte: 65 total= 366 3730
Bluetooth 受信byte: 130 total= 496 3600
Bluetooth 受信byte: 69 total= 565 3531
Bluetooth 受信byte: 56 total= 621 3475
Bluetooth 受信byte: 64 total= 685 3411
Bluetooth 受信byte: 128 total= 813 3283
Bluetooth 受信byte: 72 total= 885 3211
Bluetooth 受信byte: 120 total= 1005 3091
Bluetooth 受信byte: 130 total= 1135 2961
Bluetooth 受信byte: 126 total= 1261 2835
Bluetooth 受信byte: 129 total= 1390 2706
Bluetooth 受信byte: 133 total= 1523 2573
Bluetooth 受信byte: 58 total= 1581 2515
Bluetooth 受信byte: 64 total= 1645 2451
Bluetooth 受信byte: 64 total= 1709 2387
Bluetooth 受信byte: 67 total= 1776 2320
Bluetooth 受信byte: 189 total= 1965 2131
Bluetooth 受信byte: 65 total= 2030 2066
Bluetooth 受信byte: 133 total= 2163 1933
Bluetooth 受信byte: 58 total= 2221 1875
Bluetooth 受信byte: 64 total= 2285 1811
Bluetooth 受信byte: 67 total= 2352 1744
Bluetooth 受信byte: 189 total= 2541 1555
Bluetooth 受信byte: 129 total= 2670 1426
Bluetooth 受信byte: 127 total= 2797 1299
Bluetooth 受信byte: 64 total= 2861 1235
Bluetooth 受信byte: 131 total= 2992 1104
Bluetooth 受信byte: 132 total= 3124 972
Bluetooth 受信byte: 133 total= 3257 839
Bluetooth 受信byte: 53 total= 3310 786
Bluetooth 受信byte: 68 total= 3378 718
Bluetooth 受信byte: 123 total= 3501 595
Bluetooth 受信byte: 131 total= 3632 464
Bluetooth 受信byte: 135 total= 3767 329
Bluetooth 受信byte: 54 total= 3821 275
Bluetooth 受信byte: 64 total= 3885 211
Bluetooth 受信byte: 132 total= 4017 79
Bluetooth 受信byte: 79 total= 4096 0
ADC_END

ADC_START1
0800
Bluetooth 受信byte: 83 total= 83 4013
Bluetooth 受信byte: 128 total= 211 3885
Bluetooth 受信byte: 326 total= 537 3559
Bluetooth 受信byte: 55 total= 592 3504
Bluetooth 受信byte: 129 total= 721 3375
Bluetooth 受信byte: 63 total= 784 3312
Bluetooth 受信byte: 192 total= 976 3120
Bluetooth 受信byte: 65 total= 1041 3055
Bluetooth 受信byte: 134 total= 1175 2921
Bluetooth 受信byte: 127 total= 1302 2794
Bluetooth 受信byte: 59 total= 1361 2735
Bluetooth 受信byte: 65 total= 1426 2670
Bluetooth 受信byte: 126 total= 1552 2544
Bluetooth 受信byte: 131 total= 1683 2413
Bluetooth 受信byte: 131 total= 1814 2282
Bluetooth 受信byte: 58 total= 1872 2224
Bluetooth 受信byte: 128 total= 2000 2096
Bluetooth 受信byte: 68 total= 2068 2028
Bluetooth 受信byte: 131 total= 2199 1897
Bluetooth 受信byte: 57 total= 2256 1840
Bluetooth 受信byte: 132 total= 2388 1708
Bluetooth 受信byte: 130 total= 2518 1578
Bluetooth 受信byte: 125 total= 2643 1453
Bluetooth 受信byte: 63 total= 2706 1390
Bluetooth 受信byte: 200 total= 2906 1190
Bluetooth 受信byte: 122 total= 3028 1068
Bluetooth 受信byte: 124 total= 3152 944
Bluetooth 受信byte: 128 total= 3280 816
Bluetooth 受信byte: 68 total= 3348 748
Bluetooth 受信byte: 131 total= 3479 617
Bluetooth 受信byte: 57 total= 3536 560
Bluetooth 受信byte: 198 total= 3734 362
Bluetooth 受信byte: 58 total= 3792 304
Bluetooth 受信byte: 128 total= 3920 176
Bluetooth 受信byte: 133 total= 4053 43
Bluetooth 受信byte: 43 total= 4096 0
ADC_END

ADC_START1
0800
Bluetooth 受信byte: 115 total= 115 3981
・・・省略・・・・
END.
End Thread Exception:

R:\adc_work>

Enterのキー入力で終わります。(bluetoothの受信が追いつかない場合?に途中で停止する場合もあるようです。)
これで、実行したディレクトリ直下に、「test.wav」の録音ファイルが出来上がります。

なお、連続録音プログラムではデータをbluetoothでの転送するサイクルが間に合わない結果となりました。
その場合のデフォルト処理では抜け落ちたデータ数をマイナスで出力していました(左下イメージ)が、 その信号は余計な雑音になってしまうので、上記[UMEHOSHI ITA]の「ADC_8K_AN0_BT.c」のソース内の【A】をコメントにして、 右下のように出力しないようにしています。

この画像は、受信で得られた「test.wav」の内容をグラフ化したものです。