macsbug

Archive for 4月 2016

Part 2 of the FM radio in the ESP8266

with 2 comments

FM Radio TEA5767 を 「 mroger / TEA5767 」 ライブラリーで作りました 。  2016.04.06

「 mroger / TEA5767 」 ライブラリーは多数の機能があります。

上 :FM局名と周波数に 信号レベルを追加し 視聴中は 3D Cube が回転しています。
左下:信号レベルをアナログバーで表示。
右下:76~108MHz までの信号の強さをスペクトルで表示。


準備:
1. ライブラリー:mroger / TEA5767 Library をダウンロードする。Marcos氏に感謝。
2. ライブラリー変更: TEA5767N.cpp の  Wire.begin(); を使用不可(// のコメント)にします。
_  対応:スケッチ側で Wire.begin(4,5); を宣言し SDA,SCL 端子の割り振りをしました。

#include <Arduino.h>
#include <Wire.h>
#include <TEA5767N.h>

TEA5767N::TEA5767N() {
  //Wire.begin();                // 2016.04.06  macsbug
  initializeTransmissionData();
  muted = false;
}

3. スケッチを動かしてみる。「 FM局名 + 信号レベル + 周波数 + 3D Cube 」を表示します。


メモ:
前回ライブラリは 周波数のみの操作しかできませんでした。
mroger / TEA5767 ライブラリーは幾つかの機能があります。
サーチ:setSearchUp、setSearchDown、setSearchLowStopLevel、
_   setSearchMidStopLevel、setSearchHighStopLevel、searchNext、
_   searchNextMuting、startsSearchFrom、startsSearchFromBeginning、
_   startsSearchFromEnd、startsSearchMutingFromBeginning、
_   startsSearchMutingFromEnd、isSearchUp、isSearchDown
ミュート:mute、muteLeft、muteRight、setSoftMuteOn、setSoftMuteOff、isMuted
サウンド・オン・オフ:setStandByOn、setStandByOff、turnTheSoundBackOn、
_          turnTheLeftSoundBackOn、turnTheRightSoundBackOn
ステレオ・モノラル切り替え:setStereoReception、setMonoReception、isStereo();
フィルター:setHighCutControlOn、setHighCutControlOff、
_     setStereoNoiseCancellingOn、setStereoNoiseCancellingOff
周波数設定:selectFrequencyMuting
周波数読み取り:readFrequencyInMHz
信号レベル:getSignalLevel
その他:setStereoReception、setMonoReception

ミュート、ステレオ、モノラル、フィルター等の機能が用意されていて素晴らしい。
幾つか使用してみましたが今回使用する範囲では 使う場面はありませんでした。
最初からミュートはしない、ステレオのままとかシンプルにすると使用しない訳です。
サーチ機能はプログラムの工夫も含めて自動サーチ(自動選局)ができますが、増加か減少
時の判断に時間を要します。結果、かなりの工夫が必要となります。
使える物としては「信号レベル」と「周波数」が役に立ちます。


感想:
ライブラリーの不具合: Wire.begin(); にてSDA,SCLが設定されていない為です。
_ スケッチ側から値を渡す方法もありますが 今回はスケッチ側で宣言しました。
無線チップ:I2C接続は簡単である事とプログラムで操作できる事が素晴らしい。
_ チップから取得できる信号として周波数と信号レベルがあるのは便利です。
_ オーデーオ信号もあればスペクトラムも出来そうなのですが、無いので残念です。
_ 76〜108MHzまでの受信レベルのスペクトラムを128×64の小さな画面にグラフにして
_ みましたが、チップからの安定した値を取る為には時間を使用します。
TEA5767 FM Stereo Radio:IC単独よりもTDA1308アンプが内蔵されたもので楽でした。


スケッチ:

// FM Radio I2C TEA5767 and 3D Cube : 2016.04.06 macsbug //
// https://github.com/squix78/esp8266-oled-ssd1306       // OLED Driver
// Add drawLine to SSD1306.h and SSD1306.cpp : macsbug   // Modification
// https://github.com/mroger/TEA5767                     // FM Radio
#include <Wire.h>                                        // with mod SSD1306.cpp
#include <TEA5767N.h>                                    // FM Radio
#include "SSD1306.h"                                     // with mod SSD1306.h
#include "SSD1306Ui.h"                                   // OLED
extern "C" {
  #include "user_interface.h" 
}
SSD1306 display(0x3c,4,5);                               // OLED Initialize
TEA5767N radio = TEA5767N();                             // radio
float r, x1, z1, y2;                                     // Cube
int f[8][2];                                             // Draw box
int c[8][3];                                             // Cube
float m[]={80.0,81.3,82.5,88.3,89.7,90.5,91.6,93.0,77.3};// FM Frequency
String n[] = {"TOKYO FM","JWave","NHK FM","Ropopngi",    // FM Name
  "Inter FM","TBS","BUNKA","NIPPON","LOVEARTH"};         // FM Name
int fr = 0;                                              // Frequency
int ck = 0;                                              // chattering ck
byte g;                                                  // FM Sig Level

void setup() {                                           //
  pinMode (12, INPUT_PULLUP );                           // switch sens RL
  pinMode (13, INPUT_PULLUP );                           // switch sens FB
  Wire.begin(4,5);                                       // SDA=GPIO04,SCL=5
  display.init();                                        // OLED
  display.setFont(ArialMT_Plain_24);                     // Font
  display.setTextAlignment(TEXT_ALIGN_LEFT);             // Font direction
  display.displayOn();                                   //
  display.clear();                                       //
  display.drawString(  0, 0, "ESP8266" );                // Title
  display.drawString(  0,30, "FM RADIO");                // Title
  display.display();                                     //
  delay(3000);                                           //
  display.clear();                                       //
  display.drawString(  0, 0, n[fr] );                    // Freq name
  display.drawString(  0,28, String(m[fr],1) );          // Frequency
  display.drawString( 54,28, "MHz" );                    // Frequency
  display.display();                                     //
  radio.selectFrequency( m[fr] );                        // Freq set
  delay(3000);                                           //
  g = radio.getSignalLevel();                            // FM Sig Level
}                                                        //

void loop() {                                            //
  for ( int q = 10; q < 20; q = q + 2 ){ cube(q); }      // Expansion
  for ( int q = 20; q > 10; q = q - 2 ){ cube(q); }      // Reduction
}                                                        //

void cube(int q){                                        // Fast display
  int c[8][3] = {                                        // Cube
    {-q,-q, q},{q,-q, q},{q,q, q},{-q,q, q},             //
    {-q,-q,-q},{q,-q,-q},{q,q,-q},{-q,q,-q} };           //
  for (int a = 0; a <= 360; a = a + 3 ) {                // 0 to 360 degree
   if ( digitalRead(12) == LOW){ freq(12,+1);}           // Ball SW:+freq:RL
   if ( digitalRead(13) == LOW){ freq(13,-1);}           // Ball SW:-freq:FB
   for (int i = 0; i < 8; i++) {                         // Calculation
    r       = a * 0.0174532;                             // 1 degree
    x1      = c[i][2] * sin(r) + c[i][0] * cos(r);       // rotate X
    z1      = c[i][2] * cos(r) - c[i][0] * sin(r);       // rotate Z
    y2      = c[i][1] * cos(r) - z1      * sin(r);       // rotate Y
    f[i][0] = x1      * cos(r) - y2      * sin(r) + 64;  // X + Center
    f[i][1] = x1      * sin(r) + y2      * cos(r) + 32;  // Y + Center
    f[i][2] = c[i][1] * sin(r) + z1      * cos(r);       // Z
   }                                                     //
  display.clear();                                       //
  display.setFont(ArialMT_Plain_16);                     // Font
  display.setTextAlignment(TEXT_ALIGN_LEFT);             // Font direction
  display.drawString(  0, 0,n[fr]);                      // Freq Name
  display.drawString( 60,48,String(m[fr],1));            // Frequency
  display.setTextAlignment(TEXT_ALIGN_RIGHT);            // Font direction
  display.drawString(127, 0,String(g));                  // FM Sig level
  display.drawString(127,48,"MHz");                      // Frequency
  display.drawLine(f[0][0],f[0][1],f[1][0],f[1][1]);     // Cube
  display.drawLine(f[1][0],f[1][1],f[2][0],f[2][1]);     //
  display.drawLine(f[2][0],f[2][1],f[3][0],f[3][1]);     //
  display.drawLine(f[3][0],f[3][1],f[0][0],f[0][1]);     //
  display.drawLine(f[4][0],f[4][1],f[5][0],f[5][1]);     //
  display.drawLine(f[5][0],f[5][1],f[6][0],f[6][1]);     //
  display.drawLine(f[6][0],f[6][1],f[7][0],f[7][1]);     //
  display.drawLine(f[7][0],f[7][1],f[4][0],f[4][1]);     //
  display.drawLine(f[0][0],f[0][1],f[4][0],f[4][1]);     //
  display.drawLine(f[1][0],f[1][1],f[5][0],f[5][1]);     //
  display.drawLine(f[2][0],f[2][1],f[6][0],f[6][1]);     //
  display.drawLine(f[3][0],f[3][1],f[7][0],f[7][1]);     //
  display.drawLine(f[1][0],f[1][1],f[3][0],f[3][1]);     // cross
  display.drawLine(f[0][0],f[0][1],f[2][0],f[2][1]);     // cross
  display.display();                                     //
  delay(1);                                              // Hang-up prevention
  }                                                      //
}                                                        //

void freq(int gpio, int dir){                            //
  for ( int i = 0; i < 60; i++){ delay(10);              // chattering ck
    if ( digitalRead(gpio) == HIGH ){ ck = 1;}           // RL/FB
  }                                                      // 60 x 10 msec
  if ( ck == 0 ){                                        // Frequency Change
    fr = fr + dir; if ( fr > 8 || fr < 0 ){ fr = 0;}     // position
    display.clear();                                     // OLED
    display.setFont(ArialMT_Plain_24);                   // Font
    display.setTextAlignment(TEXT_ALIGN_LEFT);           // Font direction
    display.drawString(  0, 0, n[fr]);                   // Name
    display.drawString(  0,28, String(m[fr],1));         // Frequency
    display.drawString( 54,28, "MHz" );                  // Frequency
    display.display();                                   //
    radio.selectFrequency( m[fr] );                      // Frequency set
    delay(1000);                                         //
    g = radio.getSignalLevel();                          // FM Sig Level
  }                                                      //
  ck = 0;                                                //
}                                                        //
 

Written by macsbug

4月 6, 2016 at 6:01 am

カテゴリー: ESP8266

Make the FM Radio in ESP8266

leave a comment »

TEA5767 FM Stereo Radio と ESP8266 で FM Radio を作りました。        2016.04.04

FM局の切り替えは 傾ける事により「進む」「戻る」の動作をします。
右に傾けると次の局へ進み 後ろへ傾けると前の局へ戻ります。
この機能はボールスイッチのオン・オフで行っています。



準備:
1. D1 mini with TELEC:(D1 mini+ESP-WROOM-02 with TELEC):986円。
2. 76〜108MHz TEA5767 FM Stereo Radio (アンテナ付き):ebay = 499円。
3. Ball Swicth。ebay = 25円。
4. I2C Logic Level Converter Bi-Directional Module 5V~3.3V:ebay = 56円。
_  FM Receiver は 5V動作の為、3.3V to 5V レベルコンバーターを使用する。

5. 切れる基板、コネクター、配線材、ケース。
6. LIBRARY:simonmonk / arduino_TEA5767:周波数のみ操作が出来る。


配線図:
+5V — FM_Rx 5V。+3.3V — OLED Vcc。
D1 mini_SDA(D2,4) — OLED_SDA — FM Rx_SDA。
D1 mini_SCL( D1 ,5) — OLED_SCL — FM Rx_SCL。
Ball Switch 1 — D1 mini D6(12)、GND。
Ball Switch 2 — D1 mini D7(13)、GND。

配線と組み立て:最初に電源配線、次に I2C配線すると楽です。


メモ:
APPLICATION NOTE:Low voltage FM stereo radio with TEA5767/68
TEA5767 FM Stereo Radio:I2C信号を使用し アンテナ入力とスピーカ出力端子がある。
_    ヘッドホンアンプTDA1308搭載でAudio出力にはボリューム機能はありませんが
_    イヤホンで聴ける大きさです。ebayの製品はアンテナが含まれます。
_    電源:TEA5767は 13mA,2.5〜5Vで3.3Vで動作可能ですが このボードの規格
_       が5Vの為 I2C(SDA,SCL)へは Level Converter を接続しました。
部品価格:76〜108MHz TEA5767 FM Stereo Radioは ebayで499円。(記載時の価格)
_    aitendoは送料込みで 2040円。注:アンテナが付属品かは未記載。
ESP8266の役割:ESP8266からは I2Cで周波数を送るだけです。
_       例:radio.setFrequency( 80.0 );
WiFi 機能:スケッチでは WiFi機能は使用していません。
課題:Library:mroger/TEA5767 は高度な機能があるが まだ動作しないため課題とする。
_  その後 Library の記述に原因がある事が判明しました。:追記:2016.04.05
消費電力:USB 5V の消費電力は 130mA です。
ワイヤレス給電:消費電力が 130 mA ですのでワイヤレス給電でも充分使えています。


感想:
ラジオなんて何年も聞いていないが、作ったラジオからの曲は格別な音なんですね。
たれ流しで聞きながら過ごしたりするのもいいだろうとか気楽な気分にさせてくれる。
昔、秋葉原でちょっとブームになった 格安500円のUSBスピーカーアンプを繋ぐ。
けっしていい音とは言えませんが この単純な感じが いい雰囲気を出しています。


スケッチ:

// TEA5767 FM RADIO     : 2016.04.04  macsbug     //
#include <Wire.h>                                 //
#include <TEA5767Radio.h>                         // FM Radio
#include "SSD1306.h"                              // with mod SSD1306.h
#include "SSD1306Ui.h"                            // OLED
extern "C" {
  #include "user_interface.h" 
}                                                 //
TEA5767Radio radio = TEA5767Radio();              //
SSD1306 display(0x3c,4,5);                        // OLED Initialize
float f[] = {                                     // FM Frequency
 80.0,      81.3,   82.5,    88.3,      89.7};    //
 90.5, 91.6,   93.0,    77.3 };                   //
String n[] = {                                    // FM Name
"FM TOKYO","JWave","NHK FM","Roppongi","Inter FM",//
"TBS","BUNKA","NIPPON","LOVEARTH"};               //
int fr = 0;                                       // Frequency
int ck = 0;                                       // chattering ck

void setup(){                                     //
  pinMode (12, INPUT_PULLUP );                    // switch sens RL
  pinMode (13, INPUT_PULLUP );                    // switch sens FB
  Wire.begin(4,5);                                //
  display.init();                                 // OLED
  display.setFont(ArialMT_Plain_24);              //
  display.setTextAlignment(TEXT_ALIGN_LEFT);      //
  display.displayOn();                            //
  display.clear();                                //
  display.drawString(  0, 0, "ESP8266" );         // OLED
  display.drawString(  0,32, "FM RADIO");         //
  display.display();                              //
  delay(3000);                                    //
  display.clear();                                //
  display.drawString(  0, 0, n[fr] );             //
  display.drawString(  0,32, String(f[fr]) );     //
  display.drawString( 70,32, "MHz" );             //
  display.display();                              //
  radio.setFrequency( f[fr] );                    // FM Radio
  delay(5000);                                    //
}                                                 //

void loop(){                                      //
  ck = 0;                                         //
  if ( digitalRead(12) == LOW){ freq(12,+1);}     // + freq:RL
  if ( digitalRead(13) == LOW){ freq(13,-1);}     // - freq:FB
}                                                 //

void freq(int gpio, int dir){                     //
  for ( int i = 0; i < 60; i++){ delay(10);       // chattering ck
    if ( digitalRead(gpio) == HIGH ){ ck = 1;}    // RL/FB
  } // 60 x 10 msec if ( ck == 0 ){               // Frequency Change
  fr = fr + dir; if (fr > 8 || fr < 0 ){fr = 0;}  // position
    display.clear();                              // OLED
    display.drawString(  0, 0, n[fr]);            // Name
    display.drawString(  0,32, String(f[fr]));    // Frequency
    display.drawString( 70,32, "MHz" );           //
    display.display();                            //
    radio.setFrequency( f[fr] );                  // Frequency set
    delay(3000);                                  //
  }                                               //
}                                                 //


 

Written by macsbug

4月 4, 2016 at 8:50 am

カテゴリー: ESP8266

Using the WeMos I2C OLED 64×48

leave a comment »

WeMos の I2C OLED 64×48 Shield を D1 mini で使う方法。        2016.04.01

WeMos Electronic から OLED 64×48 I2C Shield が 3/16 に発売され3/31に到着しました。
OLEDのケースは アンテナ部を少し加工しますが D1 mini と OLED が入る大きさです。
D1 mini に OLED Shield を接続し 2つの方法を試しました。


準備:
1. D1 mini with TELEC
2. WeMos I2C OLED 64×48:$5.10
3. LED Shield Pin のハンダ付けは4つ:3.3V、GND、D2(SDA:4)、D1(SCL:5)。
4. Library:Install SparkFun_Micro_OLED_Arduino_Library:WeMosの記載。
5. Library:Modification of SSD1306 library to be used for I2C OLED:お薦め。


さあ、始めよう:
WeMos.cc の OLED Shiled には 「Install SparkFun_Micro_OLED_Arduino_Library」とある。
SparkFun_Micro_OLED_Arduino_Library は3つの問題がある。例:「MicroOLED_Cube」
1. 直ぐ動かない :MicroOLED_Cube は SPI, I2C 共用の為 I2C 用に設定する。
2. 動作が遅い  : Arduinoの速度でESP8266用に最適化されていない 。スケッチも遅い。
3. ピクセル座標軸:座標軸が異なる為に調整が必要。


1. 直ぐ動かない 件の解決方法:
_ 例:「MicroOLED_Cube」の使い方。
_ 29-36行目を以下の様に修正すると動きます。ただし動作は遅いです。

要約:
_ I2C の為、#include <SPI.h>、#define PIN_DC 8、#define PIN_CS 10、
_  MicroOLED oled(PIN_RESET, PIN_DC, PIN_CS); は使用しない。
_ I2C の為、MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration を使用する
_ #define PIN_RESET 9 は使用しないがLibraryで受け取る為 未使用のGPIOを割り振る。
_ メモ:MicroOLED oled(PIN_RESET, DC_JUMPER); 変数2個の場合 I2C動作になる。
_    MicroOLED用の名前は 「oled」になる。例:oled.begin();

#include <Wire.h>  // Include Wire if you're using I2C
//#include <SPI.h>  // Include SPI if you're using SPI
#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library

//////////////////////////
// MicroOLED Definition //
//////////////////////////
#define PIN_RESET 13  // Connect RST to pin 9
//#define PIN_DC    8  // Connect DC to pin 8
//#define PIN_CS    10 // Connect CS to pin 10
#define DC_JUMPER 0

//////////////////////////////////
// MicroOLED Object Declaration //
//////////////////////////////////
//MicroOLED oled(PIN_RESET, PIN_DC, PIN_CS); // SPI declaration
MicroOLED oled(PIN_RESET, DC_JUMPER);    // I2C declaration

2. 動作が遅い 件の解決方法:
_ ESP8266 に最適化されたライブラリーを使用する。
_ squix78FWeinb氏作成のSSD1306 Library に drawLine命令を追加したものを使用する。
_ drawLine命令は Modification of SSD1306 library to be used for I2C OLED を参照の事。


3. ピクセル座標軸 が異なる件の解決方法:
_ SSD1306.h は128×64 のサイズの為の Library です。
_ Library を 64×48 用に改修するのは難題の為 スケッチの記述で済ましました。
_ 「flipScreenVertically 」という設定(縦方向を逆にする)で行います。
_  SSD1306 Library では、Flex wire 側が下になります。
_ 左上が 32,16 右下が 95,63 の座標になります。中央は 64,40 になります。
_ この座標軸の違いをスケッチ上で補正します。

スケッチ:

// 3D cube
// Add drawLine to SSD1306.h and SSD1306.cpp : 2016.03.16 macsbug 
// Add WeMos OLED 64x48                      : 2016.03.31 macsbug 
// https://github.com/squix78/esp8266-oled-ssd1306
// WeMos OLED : 64 x 48  : x, y    x, y : CTR = 64,40    //
// flipScreenVertically : 32,16---95,16                  //
// flipScreenVertically : 32,63---95,63                  //
#include <Wire.h>                                        // with mod SSD1306.cpp
#include "SSD1306.h"                                     // with mod SSD1306.h
extern "C" {
  #include "user_interface.h" 
}
SSD1306 display(0x3c,D2,D1);                             // SDA=GPIO04,SCL=5
float r, x1, z1, y2;                                     //
int f[8][2];                                             // Draw box
int c[8][3];                                             // Cube

void setup() {                                           //
  display.init();                                        // OLED
  display.setFont(ArialMT_Plain_10);                     //
  display.setTextAlignment(TEXT_ALIGN_LEFT);             //
  display.flipScreenVertically();                        // OLED
  display.displayOn();                                   // OLED
  display.clear();                                       // OLED
}                                                        //

void loop() {                                            //
  for ( int q =  5; q < 10; q = q + 2 ){ cube(q);} // 
  for ( int q = 10; q >  5; q = q - 2 ){ cube(q);}       //
}                                                        //

void cube(int q){                                        //
  int c[8][3] = {                                        // Cube
    {-q,-q, q},{q,-q, q},{q,q, q},{-q,q, q},             //
    {-q,-q,-q},{q,-q,-q},{q,q,-q},{-q,q,-q} };           //
  for (int a = 0; a <= 360; a = a + 3 ) {                // 0 to 360 degree
   for (int i = 0; i < 8; i++) {                         //
    r       = a * 0.0174531;                             // 1 degree
    x1      = c[i][2] * sin(r) + c[i][0] * cos(r);       // rotate X
    z1      = c[i][2] * cos(r) - c[i][0] * sin(r);       // rotate Z          
    y2      = c[i][1] * cos(r) - z1      * sin(r);       // rotate Y
    f[i][0] = x1      * cos(r) - y2      * sin(r) + 64;  // X
    f[i][1] = x1      * sin(r) + y2      * cos(r) + 40;  // Y
    f[i][2] = c[i][1] * sin(r) + z1      * cos(r);       // Z
   }                                                     //
  display.clear();                                       //
  display.drawString(32,16,"3D Cube");                   //
  display.drawLine(f[0][0],f[0][1],f[1][0],f[1][1]);     //
  display.drawLine(f[1][0],f[1][1],f[2][0],f[2][1]);     //
  display.drawLine(f[2][0],f[2][1],f[3][0],f[3][1]);     //
  display.drawLine(f[3][0],f[3][1],f[0][0],f[0][1]);     //
  display.drawLine(f[4][0],f[4][1],f[5][0],f[5][1]);     //
  display.drawLine(f[5][0],f[5][1],f[6][0],f[6][1]);     //
  display.drawLine(f[6][0],f[6][1],f[7][0],f[7][1]);     //
  display.drawLine(f[7][0],f[7][1],f[4][0],f[4][1]);     //
  display.drawLine(f[0][0],f[0][1],f[4][0],f[4][1]);     //
  display.drawLine(f[1][0],f[1][1],f[5][0],f[5][1]);     //
  display.drawLine(f[2][0],f[2][1],f[6][0],f[6][1]);     //
  display.drawLine(f[3][0],f[3][1],f[7][0],f[7][1]);     //
  display.drawLine(f[1][0],f[1][1],f[3][0],f[3][1]);     // cross
  display.drawLine(f[0][0],f[0][1],f[2][0],f[2][1]);     // cross
  display.display();                                     //
  delay(1);                                              //
  }                                                      //
}                                                        //

参考:
OLED Shield:OLED Shield for WeMos D1 mini 0.66″ inch 64X48 IIC I2C $5.10
MicroPython Forumnew WEMOS Oled shield
sparkfun:Photon OLED Shield Hookup Guide
I2C OLED 128×64 SSD1306 in ESP8266


感想:
WeMosの完成度:全体的にナンバーワンですが OLED はスケッチのサンプルが不完全でした。
_ 多分論議をかもすと思います。WeMos.cc としてはフォローが失策だと思います。
ケースの大きさ:感心致しました。OLEDのケースがそのまま完成品を入れる事が出来るのです。
_ ほんのわずか大きくアンテナ部分を切る必要がありますが、USBコネクターの部分に
_ 穴を開けてピッタリに収まる姿は気持ちのいいものですし完成した姿になります。
_ ESP-12FをESP-WROOM-02 にした場合は アンテナ部分が減り まさにピッタリの
_ 大きさになります。WeMosでD1 miniのESP-WROOM-02 With TELEC版を作って欲しい。


Written by macsbug

4月 1, 2016 at 8:19 am

カテゴリー: ESP8266