macsbug

Just another WordPress.com site

Archive for 3月 2016

Try ArduCam in ESP8266

leave a comment »

ArduCAM Mini を D1 mini で動かしてみました。                                          2016.03.31

ArduCAM Mini は 200万画素 CMOS image sensor OV2640 の SPIカメラです。

D1 mini と ArduCam に8本の配線をするだけでネットワークカメラが出来ます。
今回の方法は、転送速度は遅い為 過度な期待はせずネットカメラを楽しみます。
画像は 320 x 240 の大きさで 室内を撮りました。
ケースのサイズ: 41 x 41 x 22 mm 。重量:25g。


準備:D1 mini と ArduCam OV2640 の2つ。
1. D1 mini with ESP-WROOM-02 With TELEC:D1 mini 技適対応版
2. ArduCam OV2640:ebay:2MP OV2640 Sensor Arducam Mini Camera Shield。
_ 8PINのもので幾つか種類があるので確認する事。2935円。

3. 切れる基板、低メスコネクター、配線材:秋月。
4. ケース:3Dプリンターで製作。41 x 41 x 22 mm。25g。

5. ArduCAM:ArduCam の説明を読む:ここに殆ど網羅されている。
6. サンプル及びライブラリー:ArduCAM / Arduino:ArduCAM/examples/ESP8266/
_ キャプチャー:ArduCAM_Mini_OV2640_Capture.ino:
_ キャプチャー:ArduCAM_Mini_OV2640_websocket_server
_ ビューワー:index.html:ArduCAM_Mini_OV2640_Capture/html/index.html
_ ビューワー:camera_demo.html:ArduCAM_Mini_OV2640_websocket_server/html/


配線:合計8本のみです。電源とGNDは太めの線を使用しました。
左:上のコネクターにArduCam。下の2個のコネクターにD1 miniを装着します。

rear_board_200_s


サンプル:4つありますが 直ぐ出来る物とできない物があります。
_  TFT Display + SD Card を使用する方法は準備ができていませんので試していません。
_  SD Card の使用方法は 前回のブログに記載しましたので参考にしてください。
_  ESP8266ではTFT Displayの記事は1件位で情報が少ない為 保留中です。

1. ブラウザーで画像をキャプチャーする方法。
_  Arduino-master>ArduCAM>examples>ESP8266>ArduCAM_Mini_OV2640_Capture
_  ESP8266 + OV2640 + ブラウザーで1画面を撮る。直ぐ動きます。
2. TFT Display + SD Card を使用する方法。今回はパスします。
_  ArduCAM_Mini_OV2640_Video_Streaming
3. ブラウザーで画像をキャプチャーする方法。
_  ArduCAM_Mini_OV2640_websocket_server
_  ESP8266 + OV2640 + ブラウザーで1画面を撮る事はできますが
_  ストリーミングは出来ない為、HTMLを書き換えてボタン操作を自動で押し
_  ストリーミング風にします。プログラム脳力が無い為この程度にしておきます。
_  速度は遅いので物足りないかも知れませんがこれくらいにしておきます。
4. TFT Display + SD Card を使用する方法。今回はパスします。
_  ArduCAM_REVC_Plus_OV2640_Camera_Playback:



面倒ですが、まだ、準備があります。
1. SSID と Password の設定:スケッチの冒頭に各自の値を設定します。
2. スケッチの確認と修正: 答え=OV2640 の Chip ID は「42」です。
_ スケッチでは ArduCamのOV2640のタイプを読み込んでチェックしています。
_ この値が合わないと「Can’t find OV2640 module!」というメッセージが
_ シリアルモニターに表示されます。
_ そのタイプの値は、Serial.println(pid,HEX); で記載すると解ります。
_ 修正方法:ArduCAM_Mini_OV2640_websocket_server で説明します。
_ 78行目あたりで 「pid 0x41 」をチェックしていますが 購入した物は「42 」
_ ですので「41 」を 「42」 に変更します。

[CODE]
//Check if the camera module type is OV2640
myCAM.wrSensorReg8_8(0xff, 0x01);
myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid)
if ((vid != 0x26) || (pid != 0x41)){
[/CODE]

3. ブラウザーで見る「camera_demo.html」は 使用する  IPアドレス
_  192.168.1.1 を自分の設定に変更すると便利です。例:192.168.100.41

<input type="text" maxlength="100" id="wsURL" name="URL" value="ws://192.168.1.1" />

ストリーミング風にする方法:camera_demo.html を修正します。
HTML、JavaScriptの不勉強にて納得のいかない恥ずかしい記述ですが とりあえず追加修正。
3箇所:// *** の所。caputure のボタン操作を自動的に押す様にします。

//var wsRecvMsg;
var HTTPrequest = new XMLHttpRequest();
document.getElementById("wsMessage").click();    // ***
function encode (input) {
document.getElementById("wsMessage").click();    // ***
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

Websocket Message:
<input id="wsMessage" onclick="SendMessage()" type="button" value="capture" /> // ***
</td>


参考:
ArduCAM:ArduCAM now Supports ESP8266 Arduino Board with WIFI Websocket Camera Demo
LabVIEW ESP8266 & ArduCAM for WiFi Camera Application
興味本位の Trial 安堵 Error:ESP-WROOM-02とArduCam(web camera)
VanceAnce TechnikBlog Linux,Arduino and more:Arducam高速でストリーミングできている
OmniVision:OV2640 Advanced Informattion Preliminary Datasheet


メモ:バッファー問題
sendClientData の 4096 は 1024 か 2048 にする。4096 が問題らしいが不明になっている。
これは ESP8266WiFi Library の WiFiClient.h  や lwipopts.h 内のバッファー設定値の問題かもしれない。
ClientContext.h も関係しているようだ。難しいのでこのままにしている。


追記:2016.05.20:動作状況。
1. サンプルの ArduCAM_ESP8266_OV2640_Capture は、320 x 240 以上でもキャプチャーできます。
2. static const size_t bufferSize = 4096; の 4096 は、2048 へ変更する事。2箇所あり。


感想:
OV2640は 3000円程する高いものですが ESP8266で動きそうなので ebayへ注文しました。
OV2640は アマゾン日本では、9073円します。
OV7660 は1000円以下で安いのですが情報少なく保留しました。
どこにでも高解像度のデジカメやスマホ、本格的なものでネットワークカメラがある中で
それらと比較すると精度や機能は到底及びません。製品を買った方が安いと思います。
そういう中でも SD や TFT Display等 機能を追加して 自作デジカメとか出来る訳です。
手の平に乗り 25g の軽さでどこへでも置ける簡単さが楽しい感じ。
ArduCamの使用に関しては 基本や応用が不十分で課題が残っています。


Written by macsbug

3月 31, 2016 at 7:04 am

カテゴリー: ESP8266

Basis to learn from D1 MINI

leave a comment »

D1 mini の Micro SD Sheeld を試してみました。            2016.03.26


D1 mini wemos / D1_mini_Examples : githubに解りやすいサンプルがあります。

この中にある >04.Shields > Micro_SD_Shield > ReadWrite  を試しました。
いとも簡単に マイクロSD 内へデータの書込みと読み込みができました。
このマイクロSD(FAT32)はマックでそのまま読み書きができました。
それだけですが マイクロSDを簡単に操作出来た事で楽しかった訳です。
使用するGPIOは 基板の裏に書かれており D8,D7,D6,D5 の SPI が接続されています。

他に CardInfo,Datalogger,DumpFile,Files,listfiles のスケッチがあり勉強になります。


できたファイル。


WeMos から販売されている シールド


D1 mini の サンプル スケッチは、Arduinoの様に基本がかかれ 参考になります。
マイクロSDを試す:Micro_SD_Shield の ReadWrite を試しました。
01. Basics:Blink、BlinkWithoutDelay、Fade、HelloWorld、ReadAnalogVoltage
02. Special:CallSDKFunctions、CheckFlashConfig、ConfigFile、EEPROM、Hash、
_    Servo、Ticker、Wire
03. Sensors:BMP180_BMP085、DS18x20_Temperature
04. Shields:1_Button_Shield、DHT_Pro_Shield、DHT_Shield、Micro_SD_Shield
_     Relay_Shield
05. Displays:PCD8544-Nokia-5110-84×48


準備:
1. 右:D1 mini ESP-WROOM-02 with TELEC。前回記事の技適対応のD1 mini。

2. WeMos の Micro SD Sheeld:$1.50

3. ライブラリー:D1_mini_Examples-master 。


サンプル:ReadWrite:サンプルの最低限の所だけ使用しました。SPI接続です。


#include <SPI.h>
#include <SD.h>

const int chipSelect = D8;
const int ledPin = BUILTIN_LED;
File myFile;

void setup(){
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  while (!Serial) {;} 
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()){Serial.write(myFile.read());}
    myFile.close(); }
    else {Serial.println("error opening test.txt");
  }
}

void loop(){
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
      digitalWrite(ledPin, LOW);   // LED on
    }
    myFile.close(); }
    else {Serial.println("error opening test.txt");
  }
  digitalWrite(ledPin, HIGH);      // LED off
  delay(6000);
}

 


参考:
Schematics:D1 mini 配線図。
D1 mini Shields:D1 mini シールドの一覧。
Micro SD Shield:Micro SD シールドの説明。
MicroSD Shield Schematics:Micro SD シールドの配線図。
Arduino SD Card:Arduino の SD Card。


メモ:
D1 mini の方向は 基板の端に白ドットの印がある。
D1 mini に書かれている D0 〜 D8 の GPIO の名前は スケッチでそのまま使用できる。
_ D1 mini : NodeMCU のピンマッピング で定義されています。
_ TX=GPIO_1, RX=GPIO_3, A0=ADC,
_ D0=GPIO_16, D1=GPIO_5(SCL/I2C), D2=GPIO_4(SDA/I2C),
_ D3=GPIO_0, D4=GPIO_2, D5=GPIO_14(SCK/SPI),
_ D6=GPIO_12(MISO/SPI), D7=GPIO_13MOSI/SPI, D8=GPIO_15(SS/SPI)
ESP-12F基板の LED:GPIO_2 に接続され スケッチは「BUILTIN_LED」で使用できる。
マイクロSD:センサーのデーター保存やSDのデーター送信、大容量が可能になる。


感想:
WeMos :WeMos の充実ぶりは 凄いものがある。
_ 販売先との連携、価格の安さ、周辺シールド、そして低価格、FAQもある。
_ サイト内の説明は 基本が丁寧に書かれて驚くほど充実している。
_ 配線図 や Fritzing 、GitHub(ここに集結されている) も用意され 充実している。
_ これ程まで充実したサイトは Arduino.cc 以外には見受けられなかった。
_
_ 戦略を感じる相当な手の入れようである。いったい WeMos とは?と考えてしまう程。
_ WiFi内蔵の優位と小型と低価格を武器に Arduino陣営を飲み込む勢いでもある。

_ 電子工作の基本である「直ぐ動く」が徹底して実現している。
_ 購入して D1 mini に シールドを付け USBに接続してサンプルが直ぐ動く
_ という仕組みがほぼ完璧に仕上がっている。

: 投稿時にAliExpressのWeMos Electronicに注文したD1 mini が 10個到着(TAT=25日)。
_ 今回は注文殺到か25日かかる。$41.44 で 本日のドル換算で1個469円。
_ ebay からも販売が始まり調査の為の注文も同日に到着。こちらは5日で届いた。
_ 既にシールド関係は入手済み。その後発売になったOLEDProtBoard を注文中。
_ 既に OLED 128×64 は 10個購入済み。
_ 技適化は 既に ESP-WROOM-02 with TELECを入手済み。

 


Written by macsbug

3月 26, 2016 at 6:00 am

カテゴリー: ESP8266

D1 mini を技適対応にする。

leave a comment »

ESP8266 を TELEC 化する方法。                   2016.03.24
TELEC(技適)対応の D1 mini を作りました。
D1 mini に ESP-WROOM-02 with TELEC を取り付け 総額約千円(967円)で出来ました。
記事投稿時(2016.3.24)の再調査では 総計 890円 ( $7.88) でした。


ESPシリーズ:
ESP8266 には、ESP-01 から ESP-14 まで多数の種類がある。
ESP-13 が ESP-WROOM-02 で TELEC 206-000519 が技適対応である。
画像 左:D1 mini は ESP-12F。
画像 中:ESP-WROOM-02 TELEC は ESP-13。LED は無い。
画像 右:ESP-14 ( ESP8266EX+STM8S003F3P6)

CPUは全て ESP8266EX を使用し ESP-WROOM-02 は2種類ある。
TELEC NO. 206-000519 が金属ケースに刻印の物と 無い物がある。
日本国内での使用は TELECで認証され 総務省から技術基準適合証明の認可を
受けている。金属ケースには TELEC 206-000519 の番号が表示されている。
販売先は 海外にもある。


現状と対策:
D1 mini (ESP-12F)は 高機能、小型 、低価格で使いやすいが TELECが無い。
価格はAliEXpressで453円($3.9)である。(2月末)
D1 mini を使用するには  TELEC対応の ESP-WROOM-02 に交換すれば良い。
ESP-12Fの基板上にLEDはあるが ESP-13にLEDは無い為 D1 mini のLチカ
サンプルは動作しない。動作させるには対応する番号(2)にLEDを取り付ける事。


費用対効果:
国内某販売店:2310円。D1 mini に相当する製品。
海外某販売店:D1 mini=453円 ( $4.00 )。
海外某販売店:ESP-WROOM-02 with TELEC:514円 ( $2.98 )(2月末)。*
手間は掛かるが 2310-(453+514) = 1343円の差で効果あり。(2月末)。1420円(3/24)。
* 上記価格は2月末の購入時の価格で販売価格や「円」により都度 変化する。
* 例:ESP-WROOM-02 with TELEC : $2.98 が 記事投稿時 $3.88 になっている。
* 記事投稿時(2016.3.24)価格:総計 890円。D1 mini=$4.00,ESP=$3.88:計 $7.88。


準備:
D1 mini :AliExpress = 453円。ESP-WROOM-02 with TELEC:AliExpress = 658円。

ワイヤー(ポリウレタン銅線 0.4mm,0.34mm),高耐熱テープ,半田ごて,ピンセット等。
手間:無料。


方法:D1 mini:ESP-12Fを取り外す → 配線する → ESP-13を装着 → 完成。
_ 重要:基板を固定する。専用工具を用意する。拡大鏡を用意する。専用半田ゴテ。
_ 注意:ESP-12Fの取り外しは専用工具で行う事。端子を同時に熱して
_    力を加えずに取る事。これを怠ると簡単に基板のパターンが剥がれます。
_ 注意:ESPの端子は放熱が大きい為 半田ごての温度を少し上げ短時間で行う事。



動作試験:動きました。
左:D1 mini ESP-WROOM-02 with TELEC +シールド基板+OLEDで動作試験。
右:上記の物とバッテリー,ボールスイッチを 箱(45 x 40 x 22)に入れました。
ボールスイッチ(25円)により この位置で電源オン。傾けると電源オフになります。


メモ:
基板の裏情報。
左:ESP-12F。22Pin。2 mm pitch。D1 mini で使用している。
中:ESP-WROOM-02 with TELEC。18Pin。1.5 mm pitch。
右:ESP-14 (ESP8266EX+STM8S003F3P6)。22Pin。2 mm pitch。

取り付け位置:裏側の方がやり易いがTELEC No が見えなくなる為 実施せず。
面積:ESP-WROOM-02 に交換するとアンテナ部分が無くなり更に小型になる。
ボード設定:Arduino IDE のボード設定は 「WeMoS D1 mini」で良い。
ESP-12F上のLED:GPIO02に接続され 名前が「BUILTIN_LED」である。
_ スケッチからは「BUILTIN_LED」で使用できる。Arduino UNOの13番ピンに
_ 接続されているLEDの様なもの。電源を入れて直ぐ「Lチカ」が出来る訳です。
_ このLEDは ESP-WROOM-02 には付いていません。
この記事は 私の備忘録ですので自己責任でお願い致します。


感想:
簡単に言えば「千円で技適付き最強ESPボード」が出来ました。円安が助けてくれている。
改善の余地:D1  mini は現在 最強といえども改善するべき点が幾つかある。
手間の無い方法:図面を書いて隣国の業者に頼んで最強のD1 mini を作れば良いと思う。
WeMos Electronic:この会社は「先見の明」がある。どういう会社なのだろうか?
_ 現在 輸送が遅れる程の販売数がある。3月16日=5747個、3月24日投稿時=6524個。
_ D1 miniをESP-WROOM-02 with TELEC で作れば 同様な価格になるかもしれません。
競争力:販売価格を比較すると競争力が見えてくる。日本は1/5(2310/453)なのである。
購入のポイント:海外の販売価格や輸送費,円による総額は変動し易い。
_ 常に部品価格の調査,モニター,円換算をモニターしましょう。極力Free Shippingで。


 

Written by macsbug

3月 24, 2016 at 5:17 am

カテゴリー: ESP8266

Modification of SSD1306 library to be used for I2C OLED

leave a comment »

ESP8266 で I2C OLED 128×64 SSD1306 を動かす方法の備忘録。     2016.03.21
 
ESP8266 で OLED を動かす代表的なライブラリは 2つあります。今回は の方法です。
. squix78:esp8266-oled-ssd1306 ( SSD1306 + SSD1306Ui ):squix78氏に感謝。
 
2. cmmakerclub:ESP_Adafruit_SSD1306:cmmakerclubに感謝。
_  adafruit:Adafruit-GFX-Library:adafruitに感謝。
 


 
前回は 2. の ESP_Adafruit_SSD1306 と Adafruit-GFX-Library のコンパイルエラーを修正。
_    内容は「Adafruit-GFX.h」ライブラリーを追加修正しました。
 
今回は . で 線を描画できない無い為 ライブラリーに「drawLine」命令を追加しました。
_  線の描画が可能になり 文字と線を混在して表示でき いろいろな物が出来る様になる。
_  例: display.drawLine(x0,y0,x1,y1);



 
準備:
Mac OSX Mountain Lion
Arduino IDE 1.6.5_r5
_ Library Manager:Adafuruit GFX Library by Adafuruit Version 1.1.5 INSTALLED
_ Boards Manager:esp8266 by ESP8266 Community version 2.0.0 INSTALLED
 
前回の Adafruit-GFX.h:
squix78/esp8266-oled-ssd1306:SSD1306.h
squix78/esp8266-oled-ssd1306:SSD1306.cpp
 
ESP8266 (ESP-WROOM-02):AliExpress=1個435円(TELEC 技適済)。
I2C OLED 128×64 SSD1306:ebay=1個613円。


 
手順:SSD1306.h と SSD1306.cpp に「drawLine」を追加します。( 計3つ)


 
1. SSD1306.h へ追加:「void drawLine」をリストの最後に追加します。

// Draw the border of a drawLine at the given location          // add drawLine
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);  // add drawLine

 
2. SSD1306.cpp へ追加:drawLine 内で使用する _swap_ の処理。
_  リストの冒頭にある(#include “SSD1306.h”、#include )の下に以下を追加します。

#ifndef _swap_int16_t                                           // add drawLine
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }    // add drawLine
#endif 

 
3. SSD1306.cpp へ追加:以下の「drawLine」をリストの最後に追加します。

// add drawLine
void SSD1306::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
  int steep = abs(y1 - y0) > abs(x1 - x0);
  if (steep) {
    _swap_int16_t(x0, y0);
    _swap_int16_t(x1, y1);
  }

  if (x0 > x1) {
    _swap_int16_t(x0, x1);
    _swap_int16_t(y0, y1);
  }

  int dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int err = dx / 2;
  int ystep;

  if (y0 < y1) {
    ystep = 1;
  } else {
    ystep = -1;
  }

  for (; x0<=x1; x0++) {
    if (steep) {
      setPixel(y0, x0);
    } else {
      setPixel(x0, y0);
    }
    err -= dy;
    if (err < 0) {
      y0 += ystep;
      err += dx;
    }
  }
}


 
詳細:
以下、基本も無く用語も適当かも知れませんので ご了承ください。
ライブラリーなど到底出来ないレベルで諦めていましたが なんとなくトライ。
ヒントは 「Adafruit-GFX」ライブラリーは「線」が引けると言う事。
この「線」の中味を「移植」すれば良いのではないかと 無い脳味噌で考えてみました。

「線」を描画する「drawLine」命令がある本体は「Adafruit-GFX」らしい。
そしてプログラムは cpp に書いてあるらしい。

移植を開始:
1.「Adafruit-GFX.cpp」 を「drawLine」で検索すると 196行目に「drawLine」命令がある。
_ この「drawLine」ルーチンをコピーします。(196-234行目)
_ 「drawLine」ルーチンを「SSD1306.cpp」の一番下に追加します。

2. 上記ルーチンの違いを修正します。
_ 理由は 「SSD1306.cpp」では「color」関数を使用しない為です。
_ 「,uint16_t color」「,color」「,color」 の3つを削除します。

3.「SSD1306.cpp」の定数の定義を設定します。
_ 「Adafruit-GFX.cpp」で追加した以下をコピーします。_swap_関数を宣言している所。
_ 3行を前回の Adafruit-GFX.cpp と同様に「SSD1306.cpp」の冒頭に追加します。

#ifndef _swap_int16_t 
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
#endif 


4.「SSD1306.h」には 関数の定義があり この中へ関数を記述します。
_ 中程にある drawRect 関数と同様に「void drawLine」を記述します。

void drawRect(int x, int y, int width, int height);
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);


5. 補足:
_ cmmakerclub の記述方式は「int16_t」を使用し squix78氏は「int」を使用しています。
_ squix78氏に会わせるならば「int16_t」を「int」にするとリストが奇麗になります。
_ どちらの記述でも動き 私は「int」形式にしました。

void drawLine(int x0, int y0, int x1, int y1);

 
感想:
ESP8266でトップレベルに入る squix78氏が何故 線を描画する命令を入れなかったか
わかりません。もしかすると、既にライブラリーの中に入っているかも知れません。
それでしたら取り越し苦労ですね。それとも 必要ないよ とかでしょうか。
デモプログラムには 線を描画する場面はありませんでした。
結果 squix78氏のライブラリーで drawLine により「3D Cube」が動いたので良しとします。
それにしても display.drawLine の後に delay(1) を入れなければならないのは何故なんだ。

drawLine:「Adafruit-GFX」の drawLine は とても参考になります。2点間の線の描画は
_  x0,y0,x1,y1 の + – を考慮する必要があり _swap_int16_t(x0, y0); で処理しています。
_ 2点間の増分と余りを計算する為に微分を使用しています。dx,dy,err の様です。
_ 解りやすい記述ですので 独自のルーチンが記述できるかもしれません。
_ こういう記述を見ていると これを作る人がいて 凄いな〜と実に関心致します。

素人がライブラリーに手を加えて 後で作者が新バージョンを出すと 手も足も
出なくなる恐れがありますね。
 


 
サンプル:3D Cube by macsbug


// Add drawLine to SSD1306.h and SSD1306.cpp : by macsbug
// https://github.com/squix78/esp8266-oled-ssd1306
#include <Wire.h>                                           // with mod SSD1306.cpp
#include "SSD1306.h"                                        // with mod SSD1306.h
#include "SSD1306Ui.h"                                      // OLED
extern "C" {
  #include "user_interface.h" 
}
SSD1306 display(0x3c,12,13);                                // OLED Initialize
float r, x1, z1, y2;                                        //
int f[8][2];                                                // Draw box
int x = 64;                                                 // 64=128/2
int y = 32;                                                 // 32= 64/2
int c[8][3] = {                                             // Cube
    {-20,-20, 20},{20,-20, 20},{20,20, 20},{-20,20, 20},    //
    {-20,-20,-20},{20,-20,-20},{20,20,-20},{-20,20,-20} };  //

void setup() {                                              //
  Wire.begin(12,13);                                        // SDA=GPIO012,SCL=13
  display.init();                                           // OLED
  display.setFont(ArialMT_Plain_16);                        //
  display.setTextAlignment(TEXT_ALIGN_LEFT);                //
  display.flipScreenVertically();                           // OLED
  display.displayOn();                                      // OLED
  display.clear();                                          // OLED
}                                                           //

void loop() {                                               //
  for (int a = 0; a <= 360; a = a + 3 ) {                   // 0-360 degree step 3
   for (int i = 0; i < 8; i++) {                            //
    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)  + x;     // X
    f[i][1] = x1      * sin(r) + y2      * cos(r)  + y;     // Y
    f[i][2] = c[i][1] * sin(r) + z1      * cos(r);          // Z
   }                                                        //
   display.clear();                                         //
   display.drawString(0,0,"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);                                                 //
}                                                           //


Written by macsbug

3月 20, 2016 at 6:34 am

カテゴリー: ESP8266

I2C OLED 128×64 SSD1306 in ESP8266

leave a comment »

ESP8266 で I2C OLED 128×64 SSD1306 を動かす方法の備忘録。       2016.03.20

ESP8266 で OLED を動かす代表的なライブラリは以下の2つがあります。今回は の方法です。
1. squix78:esp8266-oled-ssd1306 ( SSD1306 + SSD1306Ui ):squix78氏に感謝。

. cmmakerclub:ESP_Adafruit_SSD1306:cmmakerclubに感謝。
_  adafruit:Adafruit-GFX-Library:adafruitに感謝。



1. squix78氏 による SSD1306,SSD1306Ui ライブラリは多くの機能を持ち最高傑作です。
_  文字の奇麗さや表示方法により見やすい画面を作る事ができます。
_  使用したいフォントを作成して組み込むことができるウエブサイトは素晴らしいです。
_  文字の表示は X,Y の位置に表示する方式で表示レイアウトがしやすいです。
_  右揃え 左揃えの機能により位置合わせができる為 奇麗に表示できます。
_  WiFi受け待ち時の進行状況やページめくりの画像処理機能は見事です。
_  気になる点は「drawLine 命令」が無い為に 線を引く事ができません。
_  この件は ライブラリの解析を実施し drawLineルーチンを追加して動作しました。
_  詳細は Modification of SSD1306 library to be used for I2C OLED です。

2. ESP_Adafruit_SSD1306Adafruit-GFX Library は drawLine 命令で線を引く事が可能。
_  Arduino IDEのLibraryやBoardのバージョンにより 動く場合と動かない場合があります。
_  3D CUBE with ESP8266 and OLED(2016.01.16)の時点では動いていましたが 何かを
_  バージョンアップした為かコンパイルエラーが発生し使用できなくなりました。
_  恐らく最新のArduino IDE のバージョンで始められた方はエラーが出ると思われます。
_  使用する為に、備忘録も兼ねて解説を致します。
_  文字表示はX,Yの位置指定でなくプリント文方式で改行が行われます。
_  文字は拡大すると奇麗ではありません。フォント機能を調べる必要があります。
_  よって ライブラリーは用途によって使い分けしたほうが良いかと思います。


開発環境:
Mac OSX Mountain Lion
Arduino IDE 1.6.5_r5
_ Library Manager:Adafuruit GFX Library by Adafuruit Version 1.1.5 INSTALLED
_ Boards Manager:esp8266 by ESP8266 Community version 2.0.0 INSTALLED
LIbrary:ESP_Adafruit_SSD1306
LIbrary:Adafruit-GFX-Library
ESP8266(ESP-WROOM-02):ebayで1個435円(TELEC 技適済)。
I2C OLED 128×64 SSD1306:ebayで1個631円。


サンプルや今回のスケッチをコンパイルすると以下のエラーを表示します。
又、コンパイルエラー修正後には 128×32 の低い解像度で表示されます。

/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp: In member function ‘virtual void Adafruit_SSD1306::drawPixel(int16_t, int16_t, uint16_t)’:
/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp:215:14: error: ‘swap’ was not declared in this scope
swap(x, y);
^
/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp: In member function ‘virtual void Adafruit_SSD1306::drawFastHLine(int16_t, int16_t, int16_t, uint16_t)’:
/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp:558:16: error: ‘swap’ was not declared in this scope
swap(x, y);
^
/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp: In member function ‘virtual void Adafruit_SSD1306::drawFastVLine(int16_t, int16_t, int16_t, uint16_t)’:
/Users/imac/Documents/Arduino/libraries/ESP_Adafruit_SSD1306/ESP_Adafruit_SSD1306.cpp:626:16: error: ‘swap’ was not declared in this scope
swap(x, y);
^
コンパイル時にエラーが発生しました。


コンパイルエラーと解像度の修正は、ESP_Adafruit_SSD1306 への追加と
_ Adafruit-GFX-Library への変更を実施します。

1. コンパイルエラーを取り除く。理由:_swap_ の定義がされていない為。
_  Adafruit_GFX.h に以下を追加します。
_  場所は #define の定義してあるリストの12行目あたりに入れます。
_  #define swap(a, b) { int16_t t = a; a = b; b = t; }

2. OLED 128×64 を使用する為の変更。理由:デフォルトの設定は 128×32 の為。
_  ESP_Adafruit_SSD1306.h を以下のように変更します。
_  場所は リストの55行目あたりにあります。
_  #define SSD1306_128_64
_  // #define SSD1306_128_32
_  // #define SSD1306_96_16


メモ:
ESP_Adafruit_SSD1306 LIbrary:ESP8266用 の LIbrary で Adafruit_SSD1306 LIbrary を
_ ESP8266用に最適化したものです。Adafruit_SSD1306 LIbrary でも動作しますが
_ 速度は Arduino と同じく遅いです。ESP8266に最適化された ESP_Adafruit_SSD1306
_ は Arduinoの5倍の速度で動き ESP8266のパワーを発揮する事ができます。


OLED情報:OLEDには以下の3種類がある。
左:GNDが左端にある。中央:VCCが左端にある。右:VCCが左端にある赤い基板。
このOLEDで注意する所は、I2Cの配列が規格化されていないのも原因ですが、
端子の配列が2種類あり、正面左側の端子がVCCかGNDになっている。
交換する時に電源が逆になる場合があるので注意する事。
業者によっては
2種類の画像が同時に掲載されており どちらがくるか到着するまで解らない。
他に発光色として白と黄色+青(黄色は一番上の1行分)がある。

ebayで1個631円程度。業者としては、ebayの「gc_supremarket」という所が
画像通りの「VCCが左端にある」ものを出荷し一番安全である。

赤いタイプに注意:赤いタイプは他にも種類があるようです。
販売先の画面には、Power supply voltage: 2.8-5.0V DC とかかれている。
しかし、LDOのU2が無く3.3V以上はレギュレートされないと思われます。
その為 想像ですが5Vを接続した場合は破損する可能性があります。
左:16個の部品が使用されている。(U2,D1,R1,5,6,7,RDRS,C1,2,3,4,5,6,7,8,9)
右:10個の部品が使用されている。(R1,2,3,4,C1,2,3,4,5,6):U2,D1,ADRS なし。


感想:
よくある何かの後に起きるトラブル:ライブラリーのアップデートか何かの後に スケッチが
_ コンパイルできなくなり調べました私の脳味噌では解るまで結構時間を使いましたので
_ 自分の備忘録として書き置きしました。又、友人の所でOLEDが不明なエラーの為に
_ 動かす事が出来なかった件がこの方法で動かす事が出来る様になります。
ディスプレー環境の現状:ESP8266における見やすいディスプレーはこのOLED位しか無い。
_ Arduino IDEで開発できるTFTは1件ほどしか無く環境が整っていない。
delay(1):スケッチの終わりにある delay(1)は 必要です。これが無いとグラフックが途中で
_ 停止します。この方法は理由が解らず入れていますので対症療法的です。
_ ESP.wdtDisable(); では効果がありません。


スケッチ:以下のスケッチが動けば幸いです。OLEDのチェックにも使えます。


// 3D Cube in The ESP8266 and I2C OLED 128x64 SSD1306
// There is change in the two libraries
// 1:ESP_Adafruit_SSD1306.h Libraries:
//   https://github.com/cmmakerclub/ESP_Adafruit_SSD1306
//   change : #define SSD1306_128_64
// 2:Adafruit_GFX.h:
//   https://github.com/adafruit/Adafruit-GFX-Library
//   add to : #define swap(a, b) { int16_t t = a; a = b; b = t; }
// Library Manager:Adafuruit GFX Library by Adafuruit Version 1.1.5 INSTALLED
// Boards  Manager:esp8266 by ESP8266 Community version 2.0.0 INSTALLED
// I2C : SDA=GPIO04,SCL=GPIO05
#include <SPI.h>                                            //
#include <Wire.h>                                           //
#include <Adafruit_GFX.h>                                   // with mod
#include <ESP_Adafruit_SSD1306.h>                           // with mod
Adafruit_SSD1306 display(4);                                // OLED Reset
float r, x1, z1, y2;                                        //
int f[8][2];                                                // Draw box
int x = 64;                                                 // 64=128/2
int y = 32;                                                 // 32= 64/2
int c[8][3] = {                                             // Cube
    {-20,-20, 20},{20,-20, 20},{20,20, 20},{-20,20, 20},    //
    {-20,-20,-20},{20,-20,-20},{20,20,-20},{-20,20,-20} };  //

void setup() {                                              //
  Wire.begin(4,5);                                          // SDA=GPIO04,SCL=5
  display.begin(SSD1306_SWITCHCAPVCC, 0x3c);                // 0x78:011110+SA0+RW 
  display.clearDisplay();                                   //
  display.display();                                        //
}                                                           //

void loop() {                                               //
  for (int a = 0; a <= 360; a = a + 3 ) {                   // 0 to 360 degree
   for (int i = 0; i < 8; i++) {                            //
    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)  + x;     // X
    f[i][1] = x1      * sin(r) + y2      * cos(r)  + y;     // Y
    f[i][2] = c[i][1] * sin(r) + z1      * cos(r);          // Z
   }                                                        //
   display.clearDisplay();                                  //
   display.drawLine(f[0][0],f[0][1],f[1][0],f[1][1],WHITE); //
   display.drawLine(f[1][0],f[1][1],f[2][0],f[2][1],WHITE); //
   display.drawLine(f[2][0],f[2][1],f[3][0],f[3][1],WHITE); //
   display.drawLine(f[3][0],f[3][1],f[0][0],f[0][1],WHITE); //
   display.drawLine(f[4][0],f[4][1],f[5][0],f[5][1],WHITE); //
   display.drawLine(f[5][0],f[5][1],f[6][0],f[6][1],WHITE); //
   display.drawLine(f[6][0],f[6][1],f[7][0],f[7][1],WHITE); //
   display.drawLine(f[7][0],f[7][1],f[4][0],f[4][1],WHITE); //
   display.drawLine(f[0][0],f[0][1],f[4][0],f[4][1],WHITE); //
   display.drawLine(f[1][0],f[1][1],f[5][0],f[5][1],WHITE); //
   display.drawLine(f[2][0],f[2][1],f[6][0],f[6][1],WHITE); //
   display.drawLine(f[3][0],f[3][1],f[7][0],f[7][1],WHITE); //
   display.drawLine(f[1][0],f[1][1],f[3][0],f[3][1],WHITE); // cross
   display.drawLine(f[0][0],f[0][1],f[2][0],f[2][1],WHITE); // cross
   display.display();                                       //
  }                                                         //
  delay(1);                                                 //
}                                                           //

Written by macsbug

3月 19, 2016 at 2:52 am

カテゴリー: ESP8266

Make a voltmeter in the ADS1115 and ESP8266

with 3 comments

ESP8266 と 16bit 4ch I2C ADC ADS1115 で DC Voltmeter を作りました。             2016.03.15

基の記事はi2C 16bit ADC 4ch ADS1115 in ESP8266 を参考にしてください。
今回は 上記の内容に自動レンジ機能やキャリブレーション機能を追加し
46 x 46 x 46 mmのケースに収めました。


左:ch1=単3電池、ch2=12V Battery、ch3=ball Switch、ch4=short の電圧を測る。
右:キャリブレーション中。


準備:
ESP8266(ESP-WROOM-02)ボード:
ADS1115(紫色の基板): ebayから購入。1個331円。
SW-520D ball switch angle Tilt switch vibration switch:AliExpress1個25円。
切れる基板:3枚。[AE-D 0.3t] 秋月電子通商1枚70円。
シングルピンソケット(低メス) 1×20 :[2212S-20SG-36]秋月電商 1個60円。
ピンソケット1×8:[FH105-1x8SG/RH] 秋月電商 1個40円。
分割ロングピンソケット1×42:[FHU-1x42SG] 秋月電商 1個80円。
抵抗:100KΩ 4個 金属皮膜抵抗。秋月電子通商 1袋300円。
抵抗:10KΩ 4個 金属皮膜抵抗。秋月電子通商 1袋300円。
ピンヘッダ 2列x40P(L型,標準ピッチ) :2543-2×40 千石電商 294円。
入力コネクタ:DCジャック1.4(外形3.4)(基板用)マル信無線電機 MJ-84を使用。千石電商 74円。
入力プラグ:MJ-84に合ったDCコード 1.3(外形3.4)を使用。千石電商 263円。大きさ注意。
注:ライブラリー Adafruit_ADS1015.cpp の変更。理由:SPS速度の最適化。
_ i2C 16bit ADC 4ch ADS1115 in ESP8266 を参照願います。2カ所の修正です。
_ これを実施しない場合は読み込みデーターのチャンネルずれが起きます。
_ ADS1015_REG_CONFIG_DR_1600SPS を ADS1015_REG_CONFIG_DR_3300SPS に変更する。
_ これは 2カ所の修正です。


シールドの製作:3階立てです。
上は ch3,ch4 の入力とOLEDの端子。Ball Switch は 45度に取り付けます。
_ OLEDの配線は基板へコネクタを取り付け コネクター+ワイヤー配線を無くしました。
中は ch1,ch2 の入力端子とADS1115。
下は ESP8266。


配線:
基板は 秋月の切れる基板を使用しました。
赤い線はワイヤーで配線します。被覆カットが不要なジュンフロン線を使用。
抵抗のリード線(黒)を利用してワイヤーの配線を省略します。
OLEDとADS1115はI2C接続(SDA,SCL)ですのでGPIOの4(SDA)と5(SCL)に配線。
OLEDのSDA,SCLは内部で10KΩが内蔵されていますが念の為 2.2KΩでPull-up。
OLEDの3.3VとGND端子間に高分子コンデンサー(OS-CON)(47uf)を念の為 取り付け。
ADS1115のアドレスは ADDR=GND にし 0x48 としました。
Ball Switchは GPIO14に配線し45度で取り付け。Pull-upはスケッチにて行いました。


仕様:
_ 自動レンジ切り替え:入力の電圧に応じて自動的にゲインを変えます。
_           ゲインは 6段階あります。1 bit 0.125〜0.0078125 mV。
_ 自動有効桁数の表示:ゲインにより下3桁から下7桁までの自動表示。
_           ゲインにより有効桁数が異なる為です。
_ キャリブレーション:ch4を基準に回路及び入力ワイヤーの補正を行います。
_ 傾きセンサー   :傾きによりキャリブレーションの機能を動作させます。
_ 最大入力電圧   :36Volt 。分割抵抗(金属皮膜抵抗:100kΩ + 10kΩ を
_           使用し電源電圧 3.3Vの11倍まで可能です。
_ 電源       :USB 5Vdc。


キャリブレーション:
電源オン時にケースを水平に置くと キャリブレーションを実施します。
電源オン時にケースを傾けた場合は キャリブレーションは実施しません。
使用中にケースを傾けると キャリブレーションを実施します。
キャリブレーションは ch4 の入力を手動でショートしノイズ電圧を読み取るものです。
この値により 各chの読み取り値に補正を行います。


レンジと感度:各レンジの 1bitの電圧に 32367 を掛けると最大電圧になります。


メモ:
精度の理解がいまいちです。
_ 2/3x gain の場合は 最大+/- 6.144V の入力で、1 bit = 0.1875 mVの精度。
_ 16x gain の場合は 最大+/- 0.256V の入力で、1 bit = 0.0078125 mVの精度。

_ 電源のACノイズを測定すると3mVで抵抗分割分を加えても1bitの精度を外れる。
_ と、考えると下7桁を表示するのは意味がないかと言う事でしょうか。
_ ゲインによって精度が異なる事と、実際にどの程度が測定を実施してみると
_ 10mV位の精度でそれ以下の桁は変動しています。
_ 理解不足もありますが素人的にはこの辺にしておこうかなと思っています。

どのADCがいいか:
_ MSP3002 ADCでは mV単位が測れませんが ADS1115 はmVが測れます。
_ ADCにGAIN機能があるものは広範囲の電圧を見る事が可能という事ですね。

電源、リップル、ノイズ:
_ bit数の大きな物を使用するときは電源が気になります。
_ 1bitの電圧精度に対し如何にノイズの少ない電源を供給できるか。
_ テスターで電源のAC成分を測ると3mVのノイズがある。
_ 電源にLDO ASM1117-33を付けノイズ電圧を測ると51mVと大きく採用せず。
_ この時 前後に高分子コンデンサーを入れるが効果なく前より大きくなる。
_ OLEDの影響が僅かありOLEDの電源端子に高分子コンデンサーを取り付け。


参考:
TEXAS:ADS1115
adafuruit:ADS1115 Libraly:Adafruit_ADS1X15
adafuruit:ADS1115 Read Rate
Henry’s Beach:ARDUINO ADS1115 MODULE GETTING STARTED TUTORIAL
squix78:esp8266-oled-ssd1306


感想:
ボールスイッチは便利:角度によって接点がオンになったりオフになる物です。
_ 入力装置として通常のスイッチやタッチパネルは工作やスケッチが手間ですが
_ このスイッチは2本の線を配線するだけでスケッチも簡単です。
_ pinMode (14, INPUT_PULLUP ); GPIO端子をHIGHにする(pull-up抵抗する)
_ digitalRead(14);  この2行でできます。
_ 完成後はケースに入れますから、このスイッチを使用すると何かと便利。
_ 値段も安いのでお得ですね。尚、この手の製品で国内では1個100円します。
部品リストと価格:部品箱から使用したものが多く さほどどかからずと思いましたが
_ 完成後にリストを作ると初めての場合は結構かかるものと解る。


スケッチ:

// http://www.ti.com/lit/ds/symlink/ads1115.pdf : ADS1115:BOGI,16 bit,806 SPS
// https://github.com/adafruit/Adafruit_ADS1X15
// http://henrysbench.capnfatz.com/henrys-bench/arduino-ads1115-module-getting-started-tutorial/
// https://forums.adafruit.com/viewtopic.php?f=22&t=76452
// https://github.com/squix78/esp8266-oled-ssd1306
// Adafuruit_ADS1015.h  :ADS1115_CONVERSIONDELAY (8)   to ADS1115_CONVERSIONDELAY (9) 
// Adafuruit_ADS1015.cpp:ADS1015_REG_CONFIG_DR_1600SPS to ADS1015_REG_CONFIG_DR_3300SPS
// ADS1115 : default = GAIN_TWOTHIRDS
// ads.setGain(GAIN_TWOTHIRDS); 2/3x gain +/- 6.144V 1 bit = 0.1875    mV
// ads.setGain(GAIN_ONE);         1x gain +/- 4.096V 1 bit = 0.125     mV
// ads.setGain(GAIN_TWO);         2x gain +/- 2.048V 1 bit = 0.0625    mV
// ads.setGain(GAIN_FOUR);        4x gain +/- 1.024V 1 bit = 0.03125   mV
// ads.setGain(GAIN_EIGHT);       8x gain +/- 0.512V 1 bit = 0.015625  mV
// ads.setGain(GAIN_SIXTEEN);    16x gain +/- 0.256V 1 bit = 0.0078125 mV
// ads.begin();
// I2C ADDRESS : ADS1115 ADDR = GND : 0x48(10001000)
#include <Wire.h>                                  //
#include <Adafruit_ADS1015.h>                      // ADS1115
Adafruit_ADS1115 ads(0x48);                        // 16-bit mode
#include "SSD1306.h"                               // OLED
#include "SSD1306Ui.h"                             // OLED 
extern "C" {
  #include "user_interface.h" 
}
SSD1306 display(0x3c,4,5);                         // OLED Initialize
float g23 = 0.1875;                                // gain 2/3x
float g1  = 0.125;                                 // gain   1x
float g2  = 0.0625;                                // gain   2x
float g4  = 0.03125;                               // gain   4x
float g8  = 0.015625;                              // gain   8x
float g16 = 0.0078125;                             // gain  16x
float c   = 11;                                    // 100K + 10k ohm
float v,v1,v2,v3,v4;                               // voltage
float cal;                                         // Calibartion
int16_t r;                                         // 16 bit data
int d,d1,d2,d3,d4;                                 // digit

void setup(void) {                                 //
  display.init();                                  // OLED setup
  display.flipScreenVertically();                  // OLED setup
  display.displayOn();                             // OLED setup
  display.clear();                                 // OLED setup
  display.setFont(ArialMT_Plain_16);               // OLED setup
  display.setTextAlignment(TEXT_ALIGN_LEFT);       // OLED setup
  display.drawString(0, 0,"16bit 4ch I2C");        // title
  display.drawString(0,16,"ADS1115");              // title
  display.drawString(0,32,"Analog to Digital");    // title
  display.drawString(0,48,"Converter");            // title
  display.display();                               // title
  delay(2000);                                     // title
  display.clear();                                 // title
  display.setFont(ArialMT_Plain_24);               // title
  display.drawString(0,16,"    D.V.M");            // title
  display.display();                               // title
  pinMode (14, INPUT_PULLUP );                     // switch sens
  delay(2000);                                     //
  if ( digitalRead(14) == LOW ){ calibration();}   // calibration
}                                                  //

void loop(void) {                                  //
  if ( digitalRead(14) == HIGH){ calibration();}   // switch:calibration
  v1 = Auto_range(0); d1 = d;                      // read ch0
  v2 = Auto_range(1); d2 = d;                      // read ch1
  v3 = Auto_range(2); d3 = d;                      // read ch2
  v4 = Auto_range(3); d4 = d;                      // read ch3
  Display();                                       // OLED Display
}

float Auto_range(int ch){                                  //
  Read(23,g23,ch);                                         // +-<6.2 :2/3x gain
  if (v < 4.09 && v > -4.09){ Read( 1, g1,ch);             // +-<4.1 :  1x gain
  if (v < 2.04 && v > -2.04){ Read( 2, g2,ch);             // +-<2.1 :  2x gain
  if (v < 1.02 && v > -1.02){ Read( 4, g4,ch);             // +-<1.1 :  4x gain
  if (v < 0.52 && v > -0.52){ Read( 8, g8,ch);             // +-<0.52:  8x gain
  if (v < 0.26 && v > -0.26){ Read(16,g16,ch);             // +-<0.26: 16x gain
  }}}}}                                                    // 
  float m = 0;                                             // cal data 
  if ( v >= 0  && cal <  0 ){ m = v + cal;}                // add calibration 
  if ( v >= 0  && cal >= 0 ){ m = v - cal;}                // add calibration
  if ( v <  0  && cal <  0 ){ m = v - cal;}                // add calibration
  if ( v <  0  && cal >= 0 ){ m = v + cal;}                // add calibration
  v = m;                                                   // cal data
  return v;                                                // return voltage
}

void Read(int g,float gain,int ch){                        //
  if (g == 23){ads.setGain(GAIN_TWOTHIRDS); d=4;}          // 2/3x gain
  if (g ==  1){ads.setGain(GAIN_ONE)      ; d=3;}          //   1x gain
  if (g ==  2){ads.setGain(GAIN_TWO)      ; d=4;}          //   2x gain
  if (g ==  4){ads.setGain(GAIN_FOUR)     ; d=5;}          //   4x gain
  if (g ==  8){ads.setGain(GAIN_EIGHT)    ; d=6;}          //   8x gain
  if (g == 16){ads.setGain(GAIN_SIXTEEN)  ; d=7;}          //  16x gain
  ads.begin();                                             // gain set
  r = ads.readADC_SingleEnded(ch);                         // ch vol 16bit
  v = ( r * gain ) * c / 1000;                             // ch vol calculate
}                                                          //

void Display(){                                            // OLED Display
  display.clear();                                         //
  display.setFont(ArialMT_Plain_16);                       //
  display.setTextAlignment(TEXT_ALIGN_LEFT);               //
  display.drawString(  0, 0,"1:");                         //
  display.drawString(  0,16,"2:");                         //
  display.drawString(  0,32,"3:");                         //
  display.drawString(  0,48,"4:");                         //
  display.setTextAlignment(TEXT_ALIGN_RIGHT);              //
  display.drawString( 96, 0,String(v1,d1));                // ch 0 voltage
  display.drawString( 96,16,String(v2,d2));                // ch 1 voltage
  display.drawString( 96,32,String(v3,d3));                // ch 2 voltage
  display.drawString( 96,48,String(v4,d4));                // ch 3 voltage
  display.drawString(127, 0,"vdc");                        //
  display.drawString(127,16,"vdc");                        //
  display.drawString(127,32,"vdc");                        //
  display.drawString(127,48,"vdc");                        //
  display.display();                                       //
}                                                          //

void calibration(){                                        // ch4 cal=average
p:cal = 0;                                                 // cal start
  display.clear();                                         // 
  display.setFont(ArialMT_Plain_16);                       //
  display.setTextAlignment(TEXT_ALIGN_LEFT);               //
  display.drawString(0,00,"calibration..");                //
  display.drawString(0,32,"Short the ch4");                //
  display.display();                                       //
  delay(3000);                                             //
  for ( int i=0; i<100; i++ ){                             // 100 point 
      r = ads.readADC_SingleEnded(3);                      // ch 4 read
     v4 = ( r * g16 ) * c / 1000;                          // voltage 
    cal = cal + v4;                                        // add voltage 
    display.clear();                                       // 
    display.setTextAlignment(TEXT_ALIGN_LEFT);             // 
    display.drawString(0, 0,"zero calibration");           // 
    display.drawString(0,32,String(i));                    // 
    display.drawString(0,48,"TTL=");                       // 
    display.setTextAlignment(TEXT_ALIGN_RIGHT);            // 
    display.drawString(127,32,String(v4, 7));              // read 
    display.drawString(127,48,String(cal,7));              // total error 
    display.display();                                     //
  }                                                        // 
  cal = cal / 100;                                         // average 
  if ( cal > 0.1 || cal < -0.1 ){                          // +-0.1 limit
    display.clear();                                       // 
    display.setTextAlignment(TEXT_ALIGN_LEFT);             //
    display.drawString(0,32,"cal error");                  //
    display.display();                                     //
    delay(1000);                                           //
    goto p;                                                // re-calibration
  }                                                        //
  display.clear();                                         //
  display.setTextAlignment(TEXT_ALIGN_LEFT);               //
  display.drawString(0,48,"cal= ");                        //
  display.setTextAlignment(TEXT_ALIGN_RIGHT);              //
  display.drawString(127,48,String(cal,7));                // cal
  display.display();                                       //
  delay(2000);                                             //
}                                                          //

Written by macsbug

3月 13, 2016 at 11:49 pm

カテゴリー: ESP8266

WeMos シールド基板

leave a comment »

WeMosのセンサー付きシールド基板が到着しました。全部で11$です。   2016.03.05

今回は購入メモだけですが、ESP基板の上に乗せて必要な所だけ半田付けする。
あとはUSB接続してスケッチします。ThingSpeakでもなんでも直ぐ使える超簡単さがいい。


スイッチの基板は1個0.99$と安い。そうなると、この基板の部品を外して他のセンサーを
付ければ基板を作る必要がなくなるというアイデアが湧いてきます。
とりあえずは秋月のハサミで切れる基板(70円)を使用して超簡単電子工作ができます。
最も簡単な配線は、スイッチで電源とグランドと信号線の3本で済みます。
I2Cの部品ならば4本の配線で出来る訳です。

ただ、このままではつまらないのとカッコ悪いので、ディスプレーを接続してケースに
入れたくなります。
ケースとスケッチ:WeMosは自動書込回路付きですのでケースに入れたままスケッチを
変更する事ができます。
、、、今回は基板調査の為で製作記事でなくて申し訳ない。


D1 販売状況:AliExpressでのWeMos Electronicという販売業者の「D1 mini」は
2016年3月上旬で3646個の注文がきている。

SuperHouseからは、WeMosシールドが出てきました。

Terminal Shield Prototyping shield Power Shield

Written by macsbug

3月 5, 2016 at 11:22 am

カテゴリー: ESP8266