前回、
MacとESP-WROOM-02+FLIR LEPTONの動作内容の説明をしました。本来の使い方はiPhoneだと思うので、iPhoneのプログラムを紹介します。前回の最後に紹介した本来のデータを補間して解像度を上げたものです。
画面のタッチでColor Mapを変更できるようにしました。
作ると言っても、OpenframeworksのOSC通信サンプルを修正しているだけなので、簡単に実行できました。
今回ESP-WROOM-02のプログラムを組んでいてFLIR LEPTONの動作不安定で散々苦労しましたが、プログラムを転送した後、電源をeneloopに変えると安定します。かなり電源にシビアのようです。
Openframeworksで画像表示アプリを作成
- AppleストアでXcodeを手に入れる。
- 個人用のプログラムなら、今はなにもしなくて良いみたい(試しにSDKの私のAcountsを外しても実機テストできたので)。
- OpenframeworksのiOS最新版をダウンロードhttp://openframeworks.cc/download/。
- 解凍したフォルダを開けて examples/ios/oscReceiverExample を同じフォルダにコピー。コピーしたフォルダ名を適当な英数字に変えます。レティーナだと標準のビットマップフォントでは小さすぎるので、同じexampleフォルダのfontShapesExample/bin/data からcooperBlack.ttfをコピーしてコピーしたフォルダの同じ位置にペースト。
- iPhoneをMacに接続。できればSleepをOffにする。
- コピーしたフォルダを開けて、oscReceiverExample.xcodeprojをダブルクリック。以下Xcodeでの操作。
- まず Development Tagetを2箇所修正(iOS Debeloyment Targetを9.2に。修正しなくても動くが、いっぱい注意されます。)。
- ビルドボタンを押せば、多分iPhoneでプログラムが実行されます。
ESP-WROOM-02にプログラムを書きこむ
- Phoneのipアドレスを調べてメモ。
- Arduinoソースのsaid,password,iPhoneのip部分を修正。当然PORT番号は、Openframeworks側と同一にします。(テストをしていませんがiPhoneのテザリングで実行可能だと思います)あとはESP-WROOM-02に転送するだけ。
今回のデータは一方通行ですが、双方向通信できると思うので、そうすればiPhone側からボタン操作可能となります。前にiPhoneのGUIプログラムを紹介しているので、これを使えば今からHTMLやjavaを覚えるより私には簡単かもしれません。
で、実現できちゃいました。....双方向通信。しかもiPhoneのテザリング機能が使えるので、外に持ち出してもOK。ものすごく簡単にiPhoneとつながります。
takesan.hatenablog.com
今回のソースファイル
以下ofApp.hの内容。最初の方のPORT 番号を変えるだけです(今回は8090にした)
#pragma once #include "ofxiOS.h" #include "ofxOsc.h" // listen on port 12345 #define PORT 8090 // <-----------------ポート番号を変更する。Arduino側と合わせること!! #define NUM_MSG_STRINGS 20 class ofApp : public ofxiOSApp { public: void setup(); void update(); void draw(); void exit(); void touchDown(ofTouchEventArgs & touch); void touchMoved(ofTouchEventArgs & touch); void touchUp(ofTouchEventArgs & touch); void touchDoubleTap(ofTouchEventArgs & touch); void touchCancelled(ofTouchEventArgs & touch); void lostFocus(); void gotFocus(); void gotMemoryWarning(); void deviceOrientationChanged(int newOrientation); ofxOscReceiver receiver; int current_msg_string; string msg_strings[NUM_MSG_STRINGS]; float timers[NUM_MSG_STRINGS]; int mouseX; int mouseY; string mouseButtonState; };
以下main.mmの内容。ここでは設定を1箇所変えてレティーナを有効にする(日本語の注釈部分)
#include "ofApp.h" int main() { //Openframeworos iOSも以下がだいぶ変わった。レティーナをONにすると6plusで6の画像が拡大される //従って6plusを意識しなくていいみたい。6plusは私みたいな年寄り向き? // here are the most commonly used iOS window settings. //------------------------------------------------------ ofiOSWindowSettings settings; settings.enableRetina = true; // レティーナ用にするにははここを true にする settings.enableDepth = false; // enables depth buffer for 3d drawing. settings.enableAntiAliasing = false; // enables anti-aliasing which smooths out graphics on the screen. settings.numOfAntiAliasingSamples = 0; // number of samples used for anti-aliasing. settings.enableHardwareOrientation = false; // enables native view orientation. settings.enableHardwareOrientationAnimation = false; // enables native orientation changes to be animated. settings.glesVersion = OFXIOS_RENDERER_ES1; // type of renderer to use, ES1, ES2, etc. ofCreateWindow(settings); return ofRunApp(new ofApp); }
以下ofApp.mm めんどくさいので以下コードを全部入れ替える。
#include "ofApp.h" const int colormap_rainbow[] = {1, 3, 74, 0, 3, 74, 0, 3, 75, 0, 3, 75, 0, 3, 76, 0, 3, 76, 0, 3, 77, 0, 3, 79, 0, 3, 82, 0, 5, 85, 0, 7, 88, 0, 10, 91, 0, 14, 94, 0, 19, 98, 0, 22, 100, 0, 25, 103, 0, 28, 106, 0, 32, 109, 0, 35, 112, 0, 38, 116, 0, 40, 119, 0, 42, 123, 0, 45, 128, 0, 49, 133, 0, 50, 134, 0, 51, 136, 0, 52, 137, 0, 53, 139, 0, 54, 142, 0, 55, 144, 0, 56, 145, 0, 58, 149, 0, 61, 154, 0, 63, 156, 0, 65, 159, 0, 66, 161, 0, 68, 164, 0, 69, 167, 0, 71, 170, 0, 73, 174, 0, 75, 179, 0, 76, 181, 0, 78, 184, 0, 79, 187, 0, 80, 188, 0, 81, 190, 0, 84, 194, 0, 87, 198, 0, 88, 200, 0, 90, 203, 0, 92, 205, 0, 94, 207, 0, 94, 208, 0, 95, 209, 0, 96, 210, 0, 97, 211, 0, 99, 214, 0, 102, 217, 0, 103, 218, 0, 104, 219, 0, 105, 220, 0, 107, 221, 0, 109, 223, 0, 111, 223, 0, 113, 223, 0, 115, 222, 0, 117, 221, 0, 118, 220, 1, 120, 219, 1, 122, 217, 2, 124, 216, 2, 126, 214, 3, 129, 212, 3, 131, 207, 4, 132, 205, 4, 133, 202, 4, 134, 197, 5, 136, 192, 6, 138, 185, 7, 141, 178, 8, 142, 172, 10, 144, 166, 10, 144, 162, 11, 145, 158, 12, 146, 153, 13, 147, 149, 15, 149, 140, 17, 151, 132, 22, 153, 120, 25, 154, 115, 28, 156, 109, 34, 158, 101, 40, 160, 94, 45, 162, 86, 51, 164, 79, 59, 167, 69, 67, 171, 60, 72, 173, 54, 78, 175, 48, 83, 177, 43, 89, 179, 39, 93, 181, 35, 98, 183, 31, 105, 185, 26, 109, 187, 23, 113, 188, 21, 118, 189, 19, 123, 191, 17, 128, 193, 14, 134, 195, 12, 138, 196, 10, 142, 197, 8, 146, 198, 6, 151, 200, 5, 155, 201, 4, 160, 203, 3, 164, 204, 2, 169, 205, 2, 173, 206, 1, 175, 207, 1, 178, 207, 1, 184, 208, 0, 190, 210, 0, 193, 211, 0, 196, 212, 0, 199, 212, 0, 202, 213, 1, 207, 214, 2, 212, 215, 3, 215, 214, 3, 218, 214, 3, 220, 213, 3, 222, 213, 4, 224, 212, 4, 225, 212, 5, 226, 212, 5, 229, 211, 5, 232, 211, 6, 232, 211, 6, 233, 211, 6, 234, 210, 6, 235, 210, 7, 236, 209, 7, 237, 208, 8, 239, 206, 8, 241, 204, 9, 242, 203, 9, 244, 202, 10, 244, 201, 10, 245, 200, 10, 245, 199, 11, 246, 198, 11, 247, 197, 12, 248, 194, 13, 249, 191, 14, 250, 189, 14, 251, 187, 15, 251, 185, 16, 252, 183, 17, 252, 178, 18, 253, 174, 19, 253, 171, 19, 254, 168, 20, 254, 165, 21, 254, 164, 21, 255, 163, 22, 255, 161, 22, 255, 159, 23, 255, 157, 23, 255, 155, 24, 255, 149, 25, 255, 143, 27, 255, 139, 28, 255, 135, 30, 255, 131, 31, 255, 127, 32, 255, 118, 34, 255, 110, 36, 255, 104, 37, 255, 101, 38, 255, 99, 39, 255, 93, 40, 255, 88, 42, 254, 82, 43, 254, 77, 45, 254, 69, 47, 254, 62, 49, 253, 57, 50, 253, 53, 52, 252, 49, 53, 252, 45, 55, 251, 39, 57, 251, 33, 59, 251, 32, 60, 251, 31, 60, 251, 30, 61, 251, 29, 61, 251, 28, 62, 250, 27, 63, 250, 27, 65, 249, 26, 66, 249, 26, 68, 248, 25, 70, 248, 24, 73, 247, 24, 75, 247, 25, 77, 247, 25, 79, 247, 26, 81, 247, 32, 83, 247, 35, 85, 247, 38, 86, 247, 42, 88, 247, 46, 90, 247, 50, 92, 248, 55, 94, 248, 59, 96, 248, 64, 98, 248, 72, 101, 249, 81, 104, 249, 87, 106, 250, 93, 108, 250, 95, 109, 250, 98, 110, 250, 100, 111, 251, 101, 112, 251, 102, 113, 251, 109, 117, 252, 116, 121, 252, 121, 123, 253, 126, 126, 253, 130, 128, 254, 135, 131, 254, 139, 133, 254, 144, 136, 254, 151, 140, 255, 158, 144, 255, 163, 146, 255, 168, 149, 255, 173, 152, 255, 176, 153, 255, 178, 155, 255, 184, 160, 255, 191, 165, 255, 195, 168, 255, 199, 172, 255, 203, 175, 255, 207, 179, 255, 211, 182, 255, 216, 185, 255, 218, 190, 255, 220, 196, 255, 222, 200, 255, 225, 202, 255, 227, 204, 255, 230, 206, 255, 233, 208}; const int colormap_ironblack[] = {255, 255, 255, 253, 253, 253, 251, 251, 251, 249, 249, 249, 247, 247, 247, 245, 245, 245, 243, 243, 243, 241, 241, 241, 239, 239, 239, 237, 237, 237, 235, 235, 235, 233, 233, 233, 231, 231, 231, 229, 229, 229, 227, 227, 227, 225, 225, 225, 223, 223, 223, 221, 221, 221, 219, 219, 219, 217, 217, 217, 215, 215, 215, 213, 213, 213, 211, 211, 211, 209, 209, 209, 207, 207, 207, 205, 205, 205, 203, 203, 203, 201, 201, 201, 199, 199, 199, 197, 197, 197, 195, 195, 195, 193, 193, 193, 191, 191, 191, 189, 189, 189, 187, 187, 187, 185, 185, 185, 183, 183, 183, 181, 181, 181, 179, 179, 179, 177, 177, 177, 175, 175, 175, 173, 173, 173, 171, 171, 171, 169, 169, 169, 167, 167, 167, 165, 165, 165, 163, 163, 163, 161, 161, 161, 159, 159, 159, 157, 157, 157, 155, 155, 155, 153, 153, 153, 151, 151, 151, 149, 149, 149, 147, 147, 147, 145, 145, 145, 143, 143, 143, 141, 141, 141, 139, 139, 139, 137, 137, 137, 135, 135, 135, 133, 133, 133, 131, 131, 131, 129, 129, 129, 126, 126, 126, 124, 124, 124, 122, 122, 122, 120, 120, 120, 118, 118, 118, 116, 116, 116, 114, 114, 114, 112, 112, 112, 110, 110, 110, 108, 108, 108, 106, 106, 106, 104, 104, 104, 102, 102, 102, 100, 100, 100, 98, 98, 98, 96, 96, 96, 94, 94, 94, 92, 92, 92, 90, 90, 90, 88, 88, 88, 86, 86, 86, 84, 84, 84, 82, 82, 82, 80, 80, 80, 78, 78, 78, 76, 76, 76, 74, 74, 74, 72, 72, 72, 70, 70, 70, 68, 68, 68, 66, 66, 66, 64, 64, 64, 62, 62, 62, 60, 60, 60, 58, 58, 58, 56, 56, 56, 54, 54, 54, 52, 52, 52, 50, 50, 50, 48, 48, 48, 46, 46, 46, 44, 44, 44, 42, 42, 42, 40, 40, 40, 38, 38, 38, 36, 36, 36, 34, 34, 34, 32, 32, 32, 30, 30, 30, 28, 28, 28, 26, 26, 26, 24, 24, 24, 22, 22, 22, 20, 20, 20, 18, 18, 18, 16, 16, 16, 14, 14, 14, 12, 12, 12, 10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 0, 0, 0, 0, 0, 9, 2, 0, 16, 4, 0, 24, 6, 0, 31, 8, 0, 38, 10, 0, 45, 12, 0, 53, 14, 0, 60, 17, 0, 67, 19, 0, 74, 21, 0, 82, 23, 0, 89, 25, 0, 96, 27, 0, 103, 29, 0, 111, 31, 0, 118, 36, 0, 120, 41, 0, 121, 46, 0, 122, 51, 0, 123, 56, 0, 124, 61, 0, 125, 66, 0, 126, 71, 0, 127, 76, 1, 128, 81, 1, 129, 86, 1, 130, 91, 1, 131, 96, 1, 132, 101, 1, 133, 106, 1, 134, 111, 1, 135, 116, 1, 136, 121, 1, 136, 125, 2, 137, 130, 2, 137, 135, 3, 137, 139, 3, 138, 144, 3, 138, 149, 4, 138, 153, 4, 139, 158, 5, 139, 163, 5, 139, 167, 5, 140, 172, 6, 140, 177, 6, 140, 181, 7, 141, 186, 7, 141, 189, 10, 137, 191, 13, 132, 194, 16, 127, 196, 19, 121, 198, 22, 116, 200, 25, 111, 203, 28, 106, 205, 31, 101, 207, 34, 95, 209, 37, 90, 212, 40, 85, 214, 43, 80, 216, 46, 75, 218, 49, 69, 221, 52, 64, 223, 55, 59, 224, 57, 49, 225, 60, 47, 226, 64, 44, 227, 67, 42, 228, 71, 39, 229, 74, 37, 230, 78, 34, 231, 81, 32, 231, 85, 29, 232, 88, 27, 233, 92, 24, 234, 95, 22, 235, 99, 19, 236, 102, 17, 237, 106, 14, 238, 109, 12, 239, 112, 12, 240, 116, 12, 240, 119, 12, 241, 123, 12, 241, 127, 12, 242, 130, 12, 242, 134, 12, 243, 138, 12, 243, 141, 13, 244, 145, 13, 244, 149, 13, 245, 152, 13, 245, 156, 13, 246, 160, 13, 246, 163, 13, 247, 167, 13, 247, 171, 13, 248, 175, 14, 248, 178, 15, 249, 182, 16, 249, 185, 18, 250, 189, 19, 250, 192, 20, 251, 196, 21, 251, 199, 22, 252, 203, 23, 252, 206, 24, 253, 210, 25, 253, 213, 27, 254, 217, 28, 254, 220, 29, 255, 224, 30, 255, 227, 39, 255, 229, 53, 255, 231, 67, 255, 233, 81, 255, 234, 95, 255, 236, 109, 255, 238, 123, 255, 240, 137, 255, 242, 151, 255, 244, 165, 255, 246, 179, 255, 248, 193, 255, 249, 207, 255, 251, 221, 255, 253, 235, 255, 255, 24}; uint8_t mat[61][81]; int mathigh[119][159]; float min1,max1,tem1; string linex; ofFile datax; ofTrueTypeFont Font1,Font2; const int *colormap; int color=0; //-------------------------------------------------------------- void ofApp::setup(){ //ofSetOrientation(OF_ORIENTATION_90_LEFT); // listen on the given port cout << "listening for osc messages on port " << PORT << "\n"; receiver.setup( PORT ); current_msg_string = 0; mouseX = 0; mouseY = 0; mouseButtonState = ""; Font1.load("cooperBlack.ttf", 18, true, true, true); Font2.load("cooperBlack.ttf", 48, true, true, true); ofBackground( 0,0,0); colormap = colormap_rainbow; } //-------------------------------------------------------------- void ofApp::update(){ //You might want to have a heatbeat ofxOscSender here //sending every 60 frames or so. // hide old messages for( int i=0; i<NUM_MSG_STRINGS; i++ ){ if( timers[i] < ofGetElapsedTimef() ) msg_strings[i] = ""; } // check for waiting messages while( receiver.hasWaitingMessages() ){ // get the next message ofxOscMessage m; receiver.getNextMessage(m); if(m.getAddress() == "/img_8"){ linex = m.getArgAsString(0); if(linex[0]==0x3c) linex[0]=0; for(int yy=0;yy<82;yy++){ if(yy != 81) mat[linex[0]][yy]=uint8_t(linex[yy+1]); else if(yy != 0) mat[linex[0]][yy-1]=uint8_t(linex[yy]); } } else if(m.getAddress() == "/minmax" ){ min1=m.getArgAsFloat(0); max1=m.getArgAsFloat(1); tem1=m.getArgAsFloat(2); } } } //-------------------------------------------------------------- void ofApp::draw(){ string buf; ofSetColor(255,210,0); Font2.drawString("Thermalcam!!", 65, 170); buf = "Min=" + ofToString(min1,2); ofSetColor(100,100,255); Font1.drawString(buf, 15, 360); buf = "Max=" + ofToString(max1,2); ofSetColor(255,0,0); Font1.drawString(buf, 460, 360); buf = "Temp=" + ofToString(tem1,2); ofSetColor(255,255,255); Font1.drawString(buf, 220, 310); ofSetColor(255,110,0); Font1.drawString("by Takesan", 460, 1070); ofSetColor(120,120,255); ofDrawRectangle(178,48+290,260,29); for(int i=0;i<256;i++) { //<--------温度確認用の帯を描画 ofSetColor( colormap[3*i], colormap[3*i+1], colormap[3*i+2]); ofDrawLine(i+180, 340, i+180, 365); } for (int i=0;i<60;i++){ //<---------まず縦横を拡張 for (int j=0;j<80;j++) { mathigh[i*2][j*2]=mat[i][j]; } } for (int i=0;i<119;i=i+2){ //<--------横を1つおきに左右の平均値を代入 for (int j=1;j<159;j=j+2) { mathigh[i][j]=(mathigh[i][j-1]+mathigh[i][j+1])/2; } } for (int i=1;i<119;i=i+2){ //<---------縦の平均値を代入 for (int j=0;j<159;j++) { mathigh[i][j]=(mathigh[i-1][j]+mathigh[i+1][j])/2; } } for (int i=0;i<119;i++){ //<-----------Circleを描画 for (int j=0;j<159;j++) { ofSetColor( colormap[3*mathigh[i][j]], colormap[3*mathigh[i][j]+1], colormap[3*mathigh[i][j]+2]); ofDrawCircle(j*3.8+20, i*3.8+400, 3); } } } //-------------------------------------------------------------- void ofApp::exit(){ } //-------------------------------------------------------------- void ofApp::touchDown(ofTouchEventArgs &touch){ //タッチしたらカラーマップを変更 if (color==0) { colormap = colormap_rainbow; color=1; } else if (color==1) { colormap = colormap_ironblack; color=0; } } //-------------------------------------------------------------- void ofApp::touchMoved(ofTouchEventArgs &touch){ } //-------------------------------------------------------------- void ofApp::touchUp(ofTouchEventArgs &touch){ } //-------------------------------------------------------------- void ofApp::touchDoubleTap(ofTouchEventArgs &touch){ } //-------------------------------------------------------------- void ofApp::touchCancelled(ofTouchEventArgs & touch){ } //-------------------------------------------------------------- void ofApp::lostFocus(){ } //-------------------------------------------------------------- void ofApp::gotFocus(){ } //-------------------------------------------------------------- void ofApp::gotMemoryWarning(){ } //-------------------------------------------------------------- void ofApp::deviceOrientationChanged(int newOrientation){ }
以下ESP-WROOM-02側のArduinoソース。
sip及びOSCのライブラリは前回紹介したサイトからダウンロードして、自分のコンピューターのArduino/libralyにフォルダを作ってコピーする。
extern "C"{ //<------spi.h,spi.c,spi_register.hは Arduino/liblaly の中にフォルダを作って入れておく #include <spi.h> #include <spi_register.h> } #include <Wire.h> #include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <OSCMessage.h> #define ADDRESS (0x2A) #define AGC (0x01) #define SYS (0x02) #define VID (0x03) #define OEM (0x08) #define GET (0x00) #define SET (0x01) #define RUN (0x02) #define VOSPI_FRAME_SIZE (164) #define COMMANDID_REG (0x04) #define DATALEN_REG (0x06) #define DATA0 (0x08) char ssid[] = "XXXXXXXXXXXXXXX"; // 無線ランのSSID名称:文字列。 char pass[] = "YYYYYYYYYYY"; //同上 password WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP const IPAddress outIp(XXX,XXX,X,X); // iPhoneのipアドレス 調べ方は検索してね。これがこのソフトの欠点だが //iPhoneのテザリングアドレスは固定みたいなので今度挑戦 const unsigned int outPort = 8090; // OSC 送信用ポート番号Openframeworksと合わせること const unsigned int localPort = 8080; //OSC受信用ポートのアドレス今回は使わないが使い分ければ送受信可能 char zz[82]; unsigned int min = 65536; unsigned int max = 0; float diff; void setup() { Wire.begin(); Serial.begin(115200); spi_init(HSPI); spi_clock(HSPI,1.7,2); //spi_clock(HSPI,5,2);spi_clock(HSPI,1.6666,2) Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); Serial.println("Starting UDP"); Udp.begin(localPort); Serial.print("Local port: "); Serial.println(Udp.localPort()); } static uint16_t lepton_image[63][82]; void read_lepton_frame(void) //<---SPIリードコマンド。同期と組み合わせないとうまく行かない { int i; uint16_t data = 0x000f; delay(50); //delay(185); while ((data & 0x000f == 0x000f)) { data = spi_rx16(HSPI); lepton_image[0][0] =data; for (i = 0; i < 81; i++) { lepton_image[0][i+1]=spi_rx16(HSPI); //digitalWrite(15, HIGH); } } for (int frame_number = 1; frame_number < 60; frame_number++){ for (i = 0; i < 82; i++) { lepton_image[frame_number][i] = spi_rx16(HSPI); } } } void lepton_sync(void)//<--デバッグ用=SPI同期コマンド { int i; uint16_t data = 0x000f; uint16_t aaa; while (data & 0x000f == 0x000f) { data = spi_rx16(HSPI); for (i = 0; i < 81; i++) { aaa= spi_rx16(HSPI); } } } void print_lepton_frame(void) //<--デバッグ用=コンソール表示コマンド { int i; for (int frame_number = 0; frame_number < 60; frame_number++){ for (i = 0; i < (VOSPI_FRAME_SIZE / 2); i++) { Serial.print(lepton_image[frame_number][i] ,HEX); Serial.print(","); } Serial.println(" "); } Serial.println(" "); } void lepton_command(unsigned int moduleID, unsigned int commandID, unsigned int command) { byte error; Wire.beginTransmission(ADDRESS); // Command Register is a 16-bit register located at Register Address 0x0004 Wire.write(0x00); Wire.write(0x04); if (moduleID == 0x08) //OEM module ID { Wire.write(0x48); } else { Wire.write(moduleID & 0x0f); } Wire.write( ((commandID << 2 ) & 0xfc) | (command & 0x3)); error = Wire.endTransmission(); // stop transmitting if (error != 0) { Serial.print("error="); Serial.println(error); } } void set_reg(unsigned int reg) { byte error; Wire.beginTransmission(ADDRESS); // transmit to device #4 Wire.write(reg >> 8 & 0xff); Wire.write(reg & 0xff); // sends one byte error = Wire.endTransmission(); // stop transmitting if (error != 0) { Serial.print("error="); Serial.println(error); } } int read_reg(unsigned int reg) { int reading = 0; set_reg(reg); Wire.requestFrom(ADDRESS, 2); reading = Wire.read(); // receive high byte (overwrites previous reading) reading = reading << 8; // shift high byte to be high 8 bits reading |= Wire.read(); // receive low byte as lower 8 bits return reading; } int read_data() { int i; int data; int payload_length; while (read_reg(0x2) & 0x01) { Serial.println("busy"); } payload_length = read_reg(0x6); Wire.requestFrom(ADDRESS, payload_length); //set_reg(0x08); for (i = 0; i < (payload_length / 2); i++) { data = Wire.read() << 8; data |= Wire.read(); } return data; } void loop() { int i,p; int reading = 0; String debugString; unsigned int col; float value_min,value_max,temp; long do_ffc = 0; Serial.println("SYS Telemetry Enable State"); lepton_command(SYS, 0x19>>2 ,GET); read_data(); delay(500); while(1){ min = 65536; max = 0; read_lepton_frame(); for (int frame_number = 0; frame_number < 60; frame_number++){ for (i = 0; i < 82; i++) { p=lepton_image[frame_number][i] ; if(i >= 2){ if(p < min) min = p; if(p > max) max = p; } if(i==0) lepton_image[frame_number][i]=(p & 0x00ff); } } diff = max - min; diff = diff / 256.0f; if(diff < 0.56f) diff = 0.56f; // 0.66 // delay(100); lepton_command(SYS, 0x10 >> 2 , GET); //ondo : 0x14 = chip 0x10 = aux float aux=read_data() ; // delay(100); float fpatemp = aux/ 100.0f; temp=fpatemp-273.15 ; // <-----------センサー温度 単位=℃ float fpatemp_f = fpatemp * 1.8f - 459.67f; value_min = ((0.05872 * (float)min - 472.22999f + fpatemp_f)); value_min= (value_min - 32.0f) / 1.8f; value_max = ((0.05872 * (float)max - 472.22999f + fpatemp_f)); value_max = (value_max - 32.0f) / 1.8f; Serial.println(value_min); Serial.println(value_max); //*****************Send osc data*****<------温度をOSCで送る OSCMessage msg("/minmax"); msg.add(value_min).add(value_max).add(temp); Udp.beginPacket(outIp, outPort); msg.send(Udp); Udp.endPacket(); msg.empty(); //*********************************** delay(2); //*******************14bitを8bit階調に変換********************* for (int frame_number = 0; frame_number < 60; frame_number++){ for (int i = 2; i < 82; i++) { col=lepton_image[frame_number][i] ; col = col - min; col = col / diff; if(col <= 0) col = 1; //=0 <----0にすると文字列がそこで途切れるので最低は1とした if(col > 255) col = 255; zz[i-1]=col; } zz[0]=frame_number; //<----センサーから受け取ったデータは2byte目がフレームナンバーだが改めて振り直し if(frame_number==0) zz[0]=0x3c; // <--行番号0だと文字列が切れるため、0x3c=60に変更 zz[82]='\0'; // <-----------------------文字列なので最後に必ず入れる!! //*****************Send osc data*****<--行番号を最初に入れた文字列を送る OSCMessage msg("/img_8"); msg.add(zz ); Udp.beginPacket(outIp, outPort); msg.send(Udp); Udp.endPacket(); msg.empty(); //*********************************** delay(1); // <------- 必ず必要これがないとうまく通信できない } delay(100); // <----必ず必要 } }
最後に
疲れた..........................。年だぁ......................。