■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 | 接続先 |
3V3 | 3V3 |
GND(すべて) | GND |
EN | 10kΩ経由で3V3 |
IO14 | ADXL345のSCL |
IO12 | WS2811のDin |
IO13 | N.C. |
IO15 | 10kΩ経由でGND |
IO2 | 10kΩ経由で3V3 |
IO0 | 10kΩ経由で3V3 およびISPスイッチ※ |
IO16 | N.C. |
TOUT | N.C. |
RST | 10kΩ経由で3V3 およびRSTスイッチ※ |
IO5 | N.C. |
Txd | FTDIのRxへ |
Rxd | FTDIのTxへ |
IO4 | ADXL345の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 | 接続先 |
SCL | ESPのIO14 |
SDA | ESPのIO4 |
SDO | GND |
CS | 3.3v |
Vs | 3.3v |
GND | GND |
Vdd | 3.3v |
WS2811 | 接続先 |
Din | ESPのIO12 |
Vcc | 5V |
GND | GND |
Dout | N.C. |
M78AR033-0.5 | 接続先 |
Vin | 5V |
GND | GND |
Vout | 3V3ライン |
この他、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などの処理をほぼそのまま使ってます。楽だわー。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。