2015年11月8日日曜日

「机ドン!」検出デバイス@ESP-WROOM版



■ESP版■

というわけで前回のArduino版をESP-WROOM-02でも動かしてみました。

AdafruitによるWS2811最新版ライブラリはESP8266にも対応しています。

ただ、うちのWS2811がNeoPixelではなく安物なのがいけないのか、指示した通りに光ってくれません。Greenだけは良い感じなんですが、Red/Blueについては意図した信号になっていません。トランジスタで3.3->5vへのレベルコンバータをはさんでみたのですが変わりませんでした。うーん。

400khzに切り替えても同じ。うーん。

光り方をみていると最上位ビットがズレているような感じ。

ということでLEDの点滅が意図したパターンとは違いますが、ESPでも動作させることができました。加速度センサーの値に応じてLEDを点滅させるところまではArduino版と同じですが、1分ごとにThingSpeak.comあてに各軸ごとの最大加速度を送信するようにしました。

■配線など■

相変わらずプルアップ/プルダウン/GND接続が多くて面倒くさい。

ESP-WROOM-02接続先
3V33V3
GND(すべて)GND
EN10kΩ経由で3V3
IO14ADXL345のSCL
IO12WS2811のDin
IO13N.C.
IO1510kΩ経由でGND
IO210kΩ経由で3V3
IO010kΩ経由で3V3 およびISPスイッチ※
IO16N.C.
TOUTN.C.
RST10kΩ経由で3V3 およびRSTスイッチ※
IO5N.C.
TxdFTDIのRxへ
RxdFTDIのTxへ
IO4ADXL345のSDAへ

※ISPスイッチ/RSTスイッチはノーマリーオープンのタクトスイッチで、他方をGNDにつないでください。これによりRSTとISPは常時Highレベルでスイッチを押した時にLowレベルになります。

レベル変換回路はこちらのページ(3.3V 5V レベル変換)に記載されていた「3.FETによる3.3V 5Vレベル変換」と「4.トランジスタによる3.3V 5Vレベル変換」回路を試しました。このページ上の写真にうつっているのはトランジスタによる回路です。なお、WS2811の場合は流れ込む電流が多いのか5V側のプルアップ抵抗は10kΩでは電圧が上がらなかったので1kΩを使いました。出力側の回路に応じて使い分ける必要があります。

それとFTDIを接続する際には、GND同士の接続をお忘れなく。

ADXL345接続先
SCLESPのIO14
SDAESPのIO4
SDOGND
CS3.3v
Vs3.3v
GNDGND
Vdd3.3v

WS2811接続先
DinESPのIO12
Vcc5V
GNDGND
DoutN.C.

M78AR033-0.5接続先
Vin5V
GNDGND
Vout3V3ライン

この他、ESPの3V3近くとADXL345のVccに0.1μFのパスコン、WS2811のVccとGNDの間に470uFのアルミ電解コンデンサを入れてます。

■ADXL345ライブラリの修正■

Android Citiさんのライブラリは Wire.begin(); でI2Cを初期化しているので、これを接続したピンに合わせて Wire.begin(4, 14); に変えます。ただそのままだと後日このライブラリをArduinoで使った時に動かなくて苦しみそうなので、
#ifdef ESP8266
  Wire.begin(4,15);
#else
  Wire.begin();
#endif
と書いておきます。

■ソース■

Arduino版との違いはボリューム読み込みをしていないのとThingSpeak.comへの送信処理を行っている点です。ThingSpeakへは1分ごとにその間の最高値を送るようにしています。

ESPからThingSpeak.comへの送出には鳩退治デバイスに使ったsendなどの処理をほぼそのまま使ってます。楽だわー。

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <ADXL345.h>
#include <Time.h>
//
// Wifi
//
const char *ssid = "***********";
const char *password = "***********";
WiFiClient client;
//
// NeoPixel
//
#define PIN 12
#define NUMPIXELS 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//
// ADXL345
//
ADXL345 adxl; //variable adxl is an instance of the ADXL345 library
#define MaxWaves 64
int wave[MaxWaves];
int aveX, aveY, aveZ;
void setup() {
Serial.begin(115200);
//
// NeoPixels
//
pixels.begin(); // This initializes the NeoPixel library.
//
// Wifi
//
WiFi.begin ( ssid, password );
// Wait for connection
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Serial.println("Wifi Connected");
//
// ADXL345
//
adxl.powerOn();
adxl.setActivityX(1);
adxl.setActivityY(1);
adxl.setActivityZ(1);
adxl.setInactivityX(1);
adxl.setInactivityY(1);
adxl.setInactivityZ(1);
int sumX = 0, sumY = 0, sumZ = 0;
const int times = 10;
for (int i = 0; i < times; i++) {
int x, y, z;
adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z
sumX += x;
sumY += y;
sumZ += z;
delay(100);
}
aveX = sumX / times;
aveY = sumY / times;
aveZ = sumZ / times;
//
// others
//
for (int i = 0; i < MaxWaves; i++) {
wave[i] = sin((float)i * 3.14159265 / (float)MaxWaves) * 255;
}
}
// loop counter
int xStep = -1;
int yStep = -1;
int zStep = -1;
// max loop counter
const int MaxSteps = MaxWaves * 5;
// minimum movement
int sensitive;
// range of brightness
int magX, magY, magZ;
//
// calc brightness by range and step in loop
//
int brightness(int inMag, int inStep) {
int ret = wave[inStep % MaxWaves] * inMag / 100;
if (ret < 0) ret = 0;
if (ret > 255) ret = 255;
return ret;
}
//
// set brightness range
//
int calcMag(int inDiff) {
int ret = 10;
if (inDiff > sensitive * 2) {
ret = 100;
} else if (inDiff > sensitive * 2) {
ret = 20;
}
return ret;
}
// average value of volume
int aveVol = 0;
// to get max number
int maxX = 0, maxY = 0, maxZ = 0;
int prevMinute = -1;
void loop() {
//
// RGB each brightness
//
int red = 0, green = 0, blue = 0;
//
// read volume and set sensitivity
//
aveVol = 150; // (aveVol * 9 + analogRead(20)) /10;
sensitive = aveVol / 10;
//
// read accelometer and detect movement
//
int x, y, z;
adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z
int diffX = abs(aveX - x);
int diffY = abs(aveY - y);
int diffZ = abs(aveZ - z);
if (diffX > maxX) maxX = diffX;
if (diffY > maxX) maxY = diffY;
if (diffZ > maxX) maxZ = diffZ;
if (second() == 0 && prevMinute != minute()) {
sendAxises(maxX, maxY, maxZ);
maxX = maxY = maxZ = 0;
prevMinute = minute();
}
//
// if movement is harder than expected, start flashing!
//
if (diffX > sensitive) {
if (xStep == -1) {
xStep = 0;
magX = calcMag(diffX);
}
}
if (diffY > sensitive) {
if (yStep == -1) {
yStep = 0;
magY = calcMag(diffY);
}
}
if (diffZ > sensitive) {
if (zStep == -1) {
zStep = 0;
magZ = calcMag(diffZ);
}
}
//
// manage flashing
//
if (xStep != -1) {
if (xStep > MaxSteps) {
xStep = -1;
} else {
green = brightness(magX, xStep++);
}
}
if (yStep != -1) {
if (yStep > MaxSteps) {
yStep = -1;
} else {
blue = brightness(magY, yStep++);
}
}
if (zStep != -1) {
if (zStep > MaxSteps) {
zStep = -1;
} else {
red = brightness(magZ, zStep++);
}
}
//
// controll WS2811
//
pixels.setPixelColor(0, pixels.Color(red, blue, green));
pixels.show();
// wait for 5mSec
//
delay(5);
}
void sendAxises(int inX, int inY, int inZ) {
String postStr = "";
if (inX > 0 && inX < 255) postStr = postStr + "&field1=" + String(inX);
if (inY > 0 && inY < 255) postStr = postStr + "&field2=" + String(inY);
if (inZ > 0 && inZ < 255) postStr = postStr + "&field3=" + String(inZ);
send(postStr);
Serial.println(postStr);
}
void send(String inPostStr) {
String apiKey = "**************";
Serial.print("Connecting...");
if (client.connect("184.106.153.149", 80)) { // api.thingspeak.com
Serial.print("Connected....");
String postStr = apiKey + inPostStr + "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
Serial.println("posted.");
}
client.stop();
}

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。