GR-SAKURA
GR-KURUMI
GR-COTTON
GR-CITRUS
GR-PEACH
GR-KAEDE
GR-ADZUKI
GR-LYCHEE
GR-ROSE
GR-MANGO(*)
SNShield
Web Compiler
IDE for GR
TOPPERS関連
女子美コラボ
その他
※プロデューサミーティング中
作り方使い方資料
イベント関連
作品記事
体験記事
ライブラリ
ツール
その他・過去ファイル
がじぇるね岡宮です。
画像処理をするImageライブラリを評価バージョンE1.10として公開させていただきました。
大変すみませんが、プロデューサーの皆様から多く意見を反映したいため、スケッチリファレンスはまだ作成していません。(若干言い訳がましいですね・・・)。デフォルトのサンプルコードから、ある程度読み取っていただければありがたいです。サンプルでは動体検知しかしていませんが、人物検知用のライブラリは実装しています。
ちなみに、動体検知は写真3枚、人物検知は1枚で行います。
パラメータ(感度とか)の調整はまだ入れてません。ドライバとしては入ってますので、既存ライブラリの実装を参考にお試しいただければと思います。既に純正CCRXでのWebカメラサンプルでは感度調整など簡単にお試しできますが、普通の生活空間では結局デフォルトがちょうどいいと感じがしたので、日程を優先してE1.10を公開しました。
まだ動くことだけしか確認できていませんが、ファイルのタイムスタンプが2063年なのは何故だろうと思ってました。
FATのタイムスタンプの年が7bitで1980年スタートなので、
15 - 1980 = 0xf8530x53(83) + 1980 = 2063
となっている模様です。
なので、スケッチのdateTime()は以下とする必要がありますね。
*date = FAT_DATE((t.year+2000), t.mon, t.day);
※RTCの年カウンタは16bitなのに8bitしか使えないなんて。
RTCライブラリですが、GR-SAKURA スケッチV2.02も同様の仕様となっておりだいぶ混乱しました。
年データのコンバートには、HEX2BCD()と BCD2HEX() は16ビットへの拡張をされたらいかがでしょう。
Akagawaさん、Kinoshitaさん、ありがとうございます。すみません、確認漏れしまして。
確かにライブラリの仕様変更をした方がいいですね。KURUMIも。。。
イーサネットからJPGデータを取れるように、下記の改造しようとしてるのですが、setup()内のSDメモリ初期化で、エラーがでるようになりました。何か、エラー解消のヒントありませんか?
#define __ETHER__ #define __SD__ #include <Arduino.h> #include "Image.h" #ifdef __SD__ #include "SD.h" #endif // __SD__ #include "RTC.h" #ifdef __ETHER__ #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; EthernetServer Server(80); #endif // __ETHER__ Image image[3]; RTC_TIMETYPE t; void dateTime(uint16_t* date, uint16_t* time); void setup(){ pinMode( PIN_LED0, OUTPUT ); digitalWrite( PIN_LED0, 1 ); // ON Serial.begin(9600); #ifdef __ETHER__ if (Ethernet.begin(mac) == 0) { Serial.println("DHCP fail"); } Server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); #endif // __ETHER__ while(!Serial.available()); // wait to press key Serial.read(); //dummy Serial.println("start"); #ifdef __SD__ pinMode(SS, OUTPUT); if(!SD.begin(SS)){ Serial.println("Card failed, or not present."); // ここでエラー! } else { Serial.println("Success to access SD."); } #endif // __SD__
まず、SDXCは対応してないですがどうなんでしょうか?
あ、改造したらできなくなったのですかね。
なんだか、KinoshitaさんのSAKURAとかぶりますね、、
オリジナルサンプルでは、同じSDメモリに書き込めています。どこか、イーサとリソースが被ってるんでしょうか?
リソースは被ってないと思いますが、ちょっとエミュレータが今無いため明日確認になるかもしれません。loopに移したら(mainでEtherの処理を済ませる)どうなるか、確認していただいても宜しいですか?
私の環境ですが、SDメモリ部分をコメントアウトして、実行すると、何故か、Ethernet.begin(mac);のDHCPの取得で失敗している模様で、loopまでたどり着けていないみたいです。
そもそもEthernet関連が正常に動作していない様です。
SAKURAv2の「サーバーサンプル」で試していますが、TemplateV1.00では動作して、E1.10では動作しません。
DHCPの取得に失敗します(デフォルトの192.168.0.3になります)。IPアドレスを指定してもダメでした。
私の環境に特化した問題でなくて良かった。私も、「デフォルトの192.168.0.3になります」です。
そうですか。E1.10でバグを作りこんだのですね。ちょっと今手元にKAEDEがないので確認ができないですが、明日確認してみます。
一点だけ試してみていただきたいのですが、Ether/utility/driver/r_ether.c の中にある以下を、
static descriptor_s rx_descriptors[EMAC_NUM_RX_DESCRIPTORS] __attribute__ ((section("._RX_DESC")));
static descriptor_s tx_descriptors[EMAC_NUM_TX_DESCRIPTORS] __attribute__ ((section("._TX_DESC")));
static etherbuffer_s ether_buffers __attribute__ ((section("._ETHERNET_BUFFERS")));
以下の通りに変更して試してみていただけないでしょうか?
V1.00からE1.10でEtherのソースは全然変更してないのですが、RAMのメモリ配置を変えました。マップ上で._RX_DESCセクションがアラインされておらず、それ以降の_TX_DESCと_ETHERNET_BUFFERSはアラインされています。3行全部変える必要はないかもしれないのですがお試しいただきたいです。
static descriptor_s rx_descriptors[EMAC_NUM_RX_DESCRIPTORS] __attribute__ ((aligned(0x20)));
static descriptor_s tx_descriptors[EMAC_NUM_TX_DESCRIPTORS] __attribute__ ((aligned(0x20)));
static etherbuffer_s ether_buffers __attribute__ ((aligned(0x20)));
Okamiyaさん
正解みたいです。「サーバーサンプル」は動くようになりました。
が、digipontaさんのはダメっぽいですね...。SD周りをコメントアウトするとDHCPは正しく動作するようになり、キャプチャ等も実行されている様ですが...。
Akagawaさん、ご確認ありがとうございます!まずは一個つぶせてよかったです。
SAKURAの方と現象が似てますね。
んんん。何故か、上記に掲載しているサンプルソースは、SD関係をコメントアウトして、Ether/utility/driver/r_ether.c を修正しても、DHCP失敗で、動かないみたいです、これは、私のNW環境のせいかどうか、未確認。ただし、IPアドレス指定すると、接続ができました。
一応、HTTPプロトコルが不完全だったので、そこも修正して、サンプルソースコードを、下に再掲載します。とりあえず、IEから、ピントが合っているかどうかぐらいは、分るようになったのですが、Server.write( adr, size )が途中で戻ってきて、下画像のように、データ転送が途中で切れてしまうようです。なお、同じバイト数で戻ってくる訳ではないようです。一難去ってまた一難ですが、この症状の解消は、何かヒントはありますか?
あと、SDのコメントアウトを外すと、前の投稿と同じ、SD.begin(SS)で、SDメモリが挿さってるけど、入ってないとかエラー出ました。
【サンプルプログラム】 IEからは、http://192.168.1.250/ でアクセス
#define __ETHER__ // #define __SD__ #include <Arduino.h> #include "Image.h" #ifdef __SD__ #include "SD.h" #endif // __SD__ #include "RTC.h" #ifdef __ETHER__ #include <Ethernet.h> byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; byte myIp[] = { // IPアドレスを固定で指定しました 192,168,1,250 }; EthernetServer Server(80); #endif // __ETHER__ Image image[3]; RTC_TIMETYPE t; void dateTime(uint16_t* date, uint16_t* time); void setup(){ pinMode( PIN_LED0, OUTPUT ); digitalWrite( PIN_LED0, 1 ); // ON Serial.begin(9600); while(!Serial.available()); // wait to press key Serial.read(); //dummy Serial.println("start"); #ifdef __ETHER__ #if 0 if (Ethernet.begin(mac) == 0) { Serial.println("DHCP fail"); while(1); } #else Ethernet.begin(mac, myIp ); #endif Server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); #endif // __ETHER__ #ifdef __SD__ pinMode(SS, OUTPUT); if(!SD.begin(SS)){ Serial.println("Card failed, or not present."); } else { Serial.println("Success to access SD."); } #endif // __SD__ rtc_init(); t.year = 15; t.mon = 9; t.day = 2; t.weekday = RTC_WEEK_WEDNESDAY; t.hour = 17; t.min = 0; t.second = 0; rtc_set_time(&t); for(int i = 0; i < 2; i++){ image[i].begin(); } #ifdef __SD__ SdFile::dateTimeCallback( &dateTime ); #endif // __SD__ } void loop(){ static int cnt = 0; #ifdef __ETHER__ EthernetClient client = Server.available(); if (!client.connected()) { return; } while (client.available()) { char c = client.read(); } #endif // __ETHER__ digitalWrite( PIN_LED0, 0 ); // OFF for(int i = 0; i < 3; i++){ Serial.print("Capturing image"); Serial.println(); image[i].captureStart(); while(!image[i].isCaptureFinished()); image[i].createGrayImage(); } digitalWrite( PIN_LED0, 1 ); // ON if( 0 == image[2].movingDetection(image[0].getCreatedGrayImage(), image[1].getCreatedGrayImage())){ Serial.println("finish detection"); Serial.print("Moving Number is:"); Serial.println(image[2].getMovingNumber()); Serial.print("The biggest moving is in area:"); Serial.println(image[2].getMovingArea(0)); } image[2].createJpg(); Serial.println("Write jpg to SD:"); char fn[50]; cnt++; sprintf (fn, "test%d.jpg", cnt); #ifdef __SD__ File file = SD.open(fn, FILE_WRITE); #endif // __SD__ uint8_t* adr = image[2].getCreatedJpg(); int32_t size = image[2].getCreatedJpgSize(); #ifdef __ETHER__ Server.print( "HTTP/1.1 200 OK\r\n" ); Server.print( "Content-Type: image/jpeg\r\n" ); Server.print( "\r\n" ); #endif // __ETHER__ #ifdef __ETHER__ Serial.println( size ); Serial.println( Server.write( adr, size ) ); // 途中で戻ってきてしまう(^_^;) #endif // __ETHER__ #ifdef __SD__ for (int i = 0; i < size; i++){ file.write(*adr); adr++; } file.close(); #endif // __SD__ delay(1); #ifdef __ETHER__ client.stop(); #endif // __ETHER__ Serial.println("Done."); } void dateTime(uint16_t* date, uint16_t* time) { rtc_get_time(&t); #ifdef __SD__ *date = FAT_DATE(t.year, t.mon, t.day); *time = FAT_TIME(t.hour, t.min, t.second); #endif // __SD__ }
さらに、下記の修正かけて、残りを送ろとすると、戻ってこないようです。
#if 0 Serial.println( Server.write( adr, size ) ); #else for( i=0; i<size;) { len = Server.write( &(adr[i]), (size - i) ); Serial.println( len ); if (len <= 0) { Serial.println("zero len"); break; } i += len; } #endif
-------
【補足】
httpでJPEGバイナリデータを応答する場合、簡易的には、下記の3行を送った後に続けて、JPEGバイナリデータを送れば済みます。この3行の最後は、空行です。行端コードは、LF+CR ("\r\n")。こうしとくと、htmlファイル側で、<img src= でも表示ができます。
Server.print( "HTTP/1.1 200 OK\r\n" ); Server.print( "Content-Type: image/jpeg\r\n" ); Server.print( "\r\n" );
あれ。確かにDHCP動かない。昨日は動いたと思ったんですが、なんだったんだろう...。中途半端な情報でスミマセン。
解析が遅れており申し訳ありません。今日は開発者もきちんと時間を割けませんでした。私ももう少し調べます。