サンプルコードを眺めた
ESP32とArduinoに対応しているのでpic16f1827には使えないのですが、
inoファイルのsetup関数をみていると、初期化直後にdelay(1000);とかdelay(800);をしている様子がうかがえました。
初期化して安定するまで少しだけ待った方が成功率が上がるかもしれないと思ったので、親機と子機のコード内で初期化直後に__delay_ms関数を追加しました。
▼■ESP32・Arduinoライブラリ&利用ガイド ver.2.0 [ZIP]
https://dragon-torch.tech/rf-modules/lora/e220-900t22s-jp-r2/#04
//■子機
#include <xc.h>
#pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = ON, MCLRE = ON, CP = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO = OFF, FCMEN = OFF
#pragma config WRT = OFF, STVREN = ON, BORV = LO, LVP = ON
#define _XTAL_FREQ 4000000
void init_uart(void) {
OSCCON = 0x6A; // = 01101010
// SPLLEN = 0 = 4倍PLL(加速器)は使わない
// IRCF3 IRCF2 IRCF1 IRCF0 = 1101 = 4 MHz HF
// - = 0
// SCS1 SCS0 = 10 = クロック源として「内部オシレータ」を使う
ANSELB = 0x00;// Bを全てデジタルに
// ANSB7 ANSB6 ANSB5 ANSB4 ANSB3 ANSB2 ANSB1 = 0 = ORTBのピンを全部 「デジタルI/O」 として使う。これでUARTの信号が通るようになる筈
// - = 0
APFCON0 = 0x00; /// ピンの機能引っ越し設定
//ビット 7 RXDTSEL: ピン選択ビット
// 0 => RX/DT 機能は RB1(7番ピン)で動作します
// 1 = RX/DT 機能は RB2 (8番ピン)で動作します
//ビット 6 SDO1SEL: ピン選択ビット
// 0 = SDO1 機能は RB2 (8番ピン)で動作します
// 1 = SDO1 機能は RA6 (15番ピン)で動作します
//ビット 5 SS1SEL: ピン選択ビット
// 0 = SS1 機能は RB5 (11番ピン)で動作します
// 1 = SS1 機能は RA5 (4番ピン)で動作します
//ビット 4 P2BSEL: ピン選択ビット
// 0 = P2B 機能は RB7 (13番ピン)で動作します
// 1 = P2B 機能は RA6 (15番ピン)で動作します
//ビット 3 CCP2SEL: ピン選択ビット
// 0 = CCP2/P2A 機能は RB6 (12番ピン)で動作します
// 1 = CCP2/P2A 機能は RA7 (16番ピン)で動作します
//ビット 2 P1DSEL: ピン選択ビット
// 0 = P1D 機能は RB7 (13番ピン)で動作します
// 1 = P1D 機能は RA6 (15番ピン)で動作します
//ビット 1 P1CSEL: ピン選択ビット
// 0 = P1C機能はRB6 (12番ピン)にあります
// 1 = P1C機能はRA7 (16番ピン)にあります
//ビット0 CCP1SEL: ピン選択ビット
// 0 = CCP1/P1A機能はRB3 (9番ピン)にあります
// 1 = CCP1/P1A機能はRB0 (6番ピン)にあります
TRISB = 0; // Bを全て出力に
// TRISB7 TRISB6 TRISB5 TRISB4 TRISB3 TRISB2 TRISB1 TRISB0
// 1 = PORTB pin configured as an input (tri-stated)
// 0 = PORTB pin configured as an output
TXSTAbits.BRGH = 1; // 高速モード
BAUDCONbits.BRG16 = 0; // 8bitタイマー
// BRG16: 16-bit Baud Rate Generator bit
// 1 = 16ビットの計算機を使う
// 0 = 8ビットの計算機を使う
SPBRG = 25; // 9600bps
RCSTA = 0b10010000;
// SPEN: シリアルポート有効ビット
// 1 => シリアルポート有効(RX/DT ピンと TX/CK ピンをシリアルポートピンとして設定)
// 0 = シリアルポート無効(リセット時に保持)
// RX9: 9 ビット受信有効ビット
// 1 = 9 ビット受信を選択
// 0 = 8 ビット受信を選択
// SREN: シングル受信有効ビット
// 非同期モード:Don’t care
// 同期モード – マスター:
// 1 = シングル受信を有効にする
// 0 = シングル受信を無効にする
// このビットは受信完了後にクリアされます。
// 同期モード – スレーブ Don’t care
// CREN: 連続受信イネーブルビット
// 非同期モード:
// 1 => 受信を有効にする
// 0 = 受信を無効にする
// 同期モード:
// 1 = イネーブルビット CREN がクリアされるまで連続受信を有効にする (CREN は SREN をオーバーライドします)
// 0 = 連続受信を無効にする
// ADDEN: アドレス検出イネーブルビット
// 非同期モード 9 ビット (RX9 = 1):
// 1 = アドレス検出を有効にする、割り込みを有効にする、RSR<8> がセットされたときに受信バッファにロードする
// 0 = アドレス検出を無効にする、すべてのバイトを受信する、9 番目のビットをパリティビットとして使用できる
// 非同期モード 8 ビット (RX9 = 0): Don’t care
// FERR: フレーミングエラービット
// 1 = フレーミングエラー (RCREG レジスタを読み出して次の有効バイトを受信することで更新可能)
// 0 = フレーミングエラーなし
// OERR:オーバーランエラービット
// 1 = オーバーランエラー(CRENビットをクリアすることでクリア可能)
// 0 = オーバーランエラーなし
// RX9D: 受信データの9番目のビット
// これはアドレス/データビットまたはパリティビットであり、ユーザーファームウェアで計算する必要があります。
TXSTAbits.TXEN = 1;// 送信機能をONにする
//ビット 7 CSRC: クロックソース選択ビット
//非同期モード: Don't care
//同期モード:
// 1 = マスターモード (BRG から内部でクロックを生成)
// 0 = スレーブモード (外部ソースからクロックを生成)
//ビット 6 TX9: 9 ビット送信有効ビット
// 1 = 9 ビット送信を選択
// 0 = 8 ビット送信を選択
//ビット 5 TXEN: 送信有効ビット (1)
// 1 => 送信有効
// 0 = 送信無効
//ビット 4 SYNC: EUSART モード選択ビット
// 1 = 同期モード
// 0 => 非同期モード
//ビット 3 SENDB: 送信ブレーク文字ビット
// 非同期モード:
// 1 = 次の送信時に同期ブレークを送信 (完了時にハードウェアによってクリアされます)
// 0 = 同期ブレーク送信完了
// 同期モード: Don't care
//ビット 2 BRGH: 高速ボーレート選択ビット
// 非同期モード:
// 1 = 高速
// 0 = 低速
// 同期モード:このモードでは未使用
//ビット 1 TRMT: 送信シフトレジスタ ステータスビット
// 1 = TSR 空
// 0 = TSR フル
//ビット 0 TX9D: 送信データの 9 番目のビット
// アドレス/データビットまたはパリティビットとして使用できます。
//注 1: 同期モードでは、SREN/CREN が TXEN よりも優先されます。
}
void putch(char c) {
while(!TRMT); // 送信完了を待つ
//TRMT: 送信シフトレジスタステータスビット
// 1 = TSR 空
// 0 = TSR フル
TXREG = c; // 送信
}
void main(void) {
init_uart();
__delay_ms(1000); // LoRaの起動を待つために1秒追加
unsigned char id = 1;
unsigned char val = 123;
while(1) {
__delay_ms(100); // 送信前にちょっと一休み
putch(id);
putch(val);
__delay_ms(100); // LoRaが電波を送りきるのを待つ
__delay_ms(1000);
}
}
//■親機
#include <xc.h>
#pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = ON, MCLRE = ON, CP = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO = OFF, FCMEN = OFF
#pragma config WRT = OFF, STVREN = ON, BORV = LO, LVP = ON
#define _XTAL_FREQ 4000000
unsigned char id, val;
void init_uart(void) {
OSCCON = 0x6A;// = 01101010
// SPLLEN = 0 = 4倍PLL(加速器)は使わない
// IRCF3 IRCF2 IRCF1 IRCF0 = 1101 = 4 MHz HF
// - = 0
// SCS1 SCS0 = 10 = クロック源として「内部オシレータ」を使う
ADCON0 = 0x00;
// - = 0
// CHS4 CHS3 CHS2 CHS1 CHS0 = 00000 = AN0(17番ピン)を対象にする(今は使わない)
// GO/DONE = 0 = A/D変換は実行中じゃない
// ADON = 0 = ADC(アナログ機能)をオフ 電気を使わないようにする
ANSELB = 0x00; // Bを全てデジタルに
// ANSB7 ANSB6 ANSB5 ANSB4 ANSB3 ANSB2 ANSB1 = 0 = ORTBのピンを全部 「デジタルI/O」 として使う。これでUARTの信号が通るようになる筈
// - = 0
APFCON0 = 0x80; // ピンの機能引っ越し設定
//ビット 7 RXDTSEL: ピン選択ビット
// 0 = RX/DT 機能は RB1(7番ピン)で動作します
// 1 = RX/DT 機能は RB2 (8番ピン)で動作します
//ビット 6 SDO1SEL: ピン選択ビット
// 0 = SDO1 機能は RB2 (8番ピン)で動作します
// 1 = SDO1 機能は RA6 (15番ピン)で動作します
//ビット 5 SS1SEL: ピン選択ビット
// 0 = SS1 機能は RB5 (11番ピン)で動作します
// 1 = SS1 機能は RA5 (4番ピン)で動作します
//ビット 4 P2BSEL: ピン選択ビット
// 0 = P2B 機能は RB7 (13番ピン)で動作します
// 1 = P2B 機能は RA6 (15番ピン)で動作します
//ビット 3 CCP2SEL: ピン選択ビット
// 0 = CCP2/P2A 機能は RB6 (12番ピン)で動作します
// 1 = CCP2/P2A 機能は RA7 (16番ピン)で動作します
//ビット 2 P1DSEL: ピン選択ビット
// 0 = P1D 機能は RB7 (13番ピン)で動作します
// 1 = P1D 機能は RA6 (15番ピン)で動作します
//ビット 1 P1CSEL: ピン選択ビット
// 0 = P1C機能はRB6 (12番ピン)にあります
// 1 = P1C機能はRA7 (16番ピン)にあります
//ビット0 CCP1SEL: ピン選択ビット
// 0 = CCP1/P1A機能はRB3 (9番ピン)にあります
// 1 = CCP1/P1A機能はRB0 (6番ピン)にあります
TRISB = 0xFF; // Bを全て入力に
// TRISB7 TRISB6 TRISB5 TRISB4 TRISB3 TRISB2 TRISB1 TRISB0
// 1 = PORTB pin configured as an input (tri-stated)
// 0 = PORTB pin configured as an output
TXSTAbits.BRGH = 1; // 高速モード
BAUDCONbits.BRG16 = 0;
// BRG16: 16-bit Baud Rate Generator bit
// 1 = 16ビットの計算機を使う
// 0 = 8ビットの計算機を使う
SPBRG = 25; // 9600bps
RCSTA = 0b10010000;
// SPEN: シリアルポート有効ビット
// 1 => シリアルポート有効(RX/DT ピンと TX/CK ピンをシリアルポートピンとして設定)
// 0 = シリアルポート無効(リセット時に保持)
// RX9: 9 ビット受信有効ビット
// 1 = 9 ビット受信を選択
// 0 = 8 ビット受信を選択
// SREN: シングル受信有効ビット
// 非同期モード:Don’t care
// 同期モード – マスター:
// 1 = シングル受信を有効にする
// 0 = シングル受信を無効にする
// このビットは受信完了後にクリアされます。
// 同期モード – スレーブ Don’t care
// CREN: 連続受信イネーブルビット
// 非同期モード:
// 1 => 受信を有効にする
// 0 = 受信を無効にする
// 同期モード:
// 1 = イネーブルビット CREN がクリアされるまで連続受信を有効にする (CREN は SREN をオーバーライドします)
// 0 = 連続受信を無効にする
// ADDEN: アドレス検出イネーブルビット
// 非同期モード 9 ビット (RX9 = 1):
// 1 = アドレス検出を有効にする、割り込みを有効にする、RSR<8> がセットされたときに受信バッファにロードする
// 0 = アドレス検出を無効にする、すべてのバイトを受信する、9 番目のビットをパリティビットとして使用できる
// 非同期モード 8 ビット (RX9 = 0): Don’t care
// FERR: フレーミングエラービット
// 1 = フレーミングエラー (RCREG レジスタを読み出して次の有効バイトを受信することで更新可能)
// 0 = フレーミングエラーなし
// OERR:オーバーランエラービット
// 1 = オーバーランエラー(CRENビットをクリアすることでクリア可能)
// 0 = オーバーランエラーなし
// RX9D: 受信データの9番目のビット
// これはアドレス/データビットまたはパリティビットであり、ユーザーファームウェアで計算する必要があります。
}
char uart_read(void) {
if (RCSTAbits.OERR || RCSTAbits.FERR) { // オーバーランエラー or フレーミングエラー なら
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1; // 再受信
}
while(!PIR1bits.RCIF); // データが届くのを待つ
return RCREG;
}
void main(void) {
init_uart();
__delay_ms(1000); // 親機も起動直後は少し待つ
while(1) {
id = uart_read();
val = uart_read();
if(id == 1) { //ブレークポイント
NOP();
}
}
}
結果
__delay_ms関数を親機と子機のコード内で初期化直後に追加しましたが、結果は先日と同じでした。
やはりE220-900T22Sが焼損しているかもしれません。
新しいものが届いたら交換してみましょう。
注文していたMB102が届いた
これで親機と子機を切り離して使えるようになりました。

しかしDCアダプターが足りません。
それは気づいていたのでusb給電する予定でした。
しかし家のどこを探してもUSB typeAオス - USB typeAオスがありませんでした。
あると思って探して見つかったのはUSB typeAオス - USB typeBmicroと、USB typeAオス - USB typeCだけ。
届くまで気付かなかった……。
秋月電子でUSB typeAオス - USB typeAオスが売ってなかったのでDCアダプターを注文する事にしました。
DCプラグによる給電なら6.5v~12vに対応しているそうです。
今回は12vのDCアダプターを購入しました。
▼mb102のデータシート
https://www.handsontec.com/dataspecs/mb102-ps.pdf
距離を離すならどのくらい?
仮に今回mb102へ給電出来た場合、どのくらいの距離を離して検証できたのでしょうか。
壁のそばに子機を置き、机上の親機までの距離をメジャーで測りました。


結果は190cmくらい。約2m弱でした。
きっと机上で15cmとか20cmで検証するよりは良い結果を得られるでしょう。
次に試す事
- DCアダプターが届いたら親機と子機の距離を離して検証する。
- 新しいE220-900T22Sが届いたら取替えて検証する。
- ESP32が届いたらサンプルコードを実行して成功体験を得る。