So-net無料ブログ作成
ATmarquino Arduino ブログトップ
前の10件 | -

Marudinoサポートページを立ち上げました [ATmarquino Arduino]

Img_1953.jpg新たにMaruduinoの専用blogページを立ち上げました。

http://maruduino.blog.so-net.ne.jp/

是非ご利用ください。



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Arduino互換テストボードのMaruduinoでMIDI演奏にチャレンジ [ATmarquino Arduino]

※著作権表記及び署名の改竄以外はご自由にお使いください。
※ところでヘッダー情報の4分音符の分解能とデルタタイムを使っての時間指定の計算ってどうすればいいのでしょう?。
※デルタタイムを引数としてdelay関数を使って次のイベントまでの待ち時間を生成していますが、この為delayの引数の時間とそれ以外の処理時間の累積となって、実はテンポがいい加減です。さて、どうしたものかね。
※スケッチ改良しました。多分大体テンポは合っているかと思う。

Img_1953.jpg



前からMIDIをやってみたいとは思っていたんです。

ただMIDIに関すると言うか音楽全般に関する知識は皆無、音符とか読めませんし、そんな状態なので結構苦労しています。Arduinoの例題をベースにスケッチを書いてみましたが、まだまだバグバグで、しかも複数トラックを持つフォーマットには対応していません。
ですが、楽器を鳴らせるのは楽しいですな。

現状はキーを押すとMIDI出力するとかそう言ったものではなく、MIDIファイルをROM化して、それを流しています。
本当はMIDIファイルをそのまま垂れ流す程度で済むかと思っていましたが、そうではないんですね。データを送るタイミングとかはこちらでコントロールする必要が有るみたい。

あ、ちなみに物理的な接続はやけに簡単です。

スケッチとバイナリーデータをCソースに変換するプログラムも一応。
※MIDIのフォーマット0のみに対応




Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



新 裏口からのMIDI入門―「楽器が弾けない」「楽譜が読めない」初心者必見! (I・O BOOKS)

新 裏口からのMIDI入門―「楽器が弾けない」「楽譜が読めない」初心者必見! (I・O BOOKS)

  • 作者: 御池 鮎樹
  • 出版社/メーカー: 工学社
  • 発売日: 2009/11
  • メディア: 単行本



SANWA SUPPLY KB-MID01-18 MIDIケーブル

SANWA SUPPLY KB-MID01-18 MIDIケーブル

  • 出版社/メーカー: サンワサプライ
  • メディア: エレクトロニクス


/*
 MIDI player
 
 The circuit:
 * digital in 1 connected to MIDI jack pin 5
 * MIDI jack pin 2 connected to ground
 * MIDI jack pin 4 connected to +5V through 220-ohm resistor
 Attach a MIDI cable to the jack, then to a MIDI synth, and play music.

 created 13 Jun 2006
 modified 2 Jul 2009
 by Tom Igoe 
 
 http://www.arduino.cc/en/Tutorial/MIDI
 
 */
#include <LiquidCrystal.h>
#include  <avr/pgmspace.h>

/*************************************************************************/
/* defines                                                               */
/*************************************************************************/
#define  DI13     13
#define  DI12     12
#define  DI11     11
#define  DI10     10
#define  DI9      9
#define  DI8      8
#define  DI7      7
#define  DI6      6
#define  DI5      5
#define  DI4      4
#define  DI3      3
#define  DI2      2
#define  DI1      1
#define  DI0      0
#define  AN0      14
#define  AN1      15
#define  AN2      16
#define  AN3      17
#define  AN4      18
#define  AN5      19
#define  PWM11    DI11
#define  PWM10    DI10
#define  PWM9     DI9
#define  PWM6     DI6
#define  PWM5     DI5
#define  PWM3     DI3

typedef struct 
{
  struct
  {
    unsigned char chunk[4];
    unsigned char len[4];
    unsigned char format[2];
    unsigned char tracks[2];
    unsigned char period[2];
  } header;  

  struct
  {
    unsigned char type[4];
    unsigned char len[4];
    unsigned char data[4];
  } track;  
} MIDI;

static unsigned long swap_l( unsigned char src[] );
static unsigned short swap_w( unsigned char src[] );

extern const unsigned char PROGMEM midi_data[];
LiquidCrystal lcd(DI2,DI3,DI4,DI5,DI6,DI7);
unsigned long data_len;
unsigned short period;
PGM_P ptr;

void setup()
{
  MIDI *midi = (MIDI *)malloc( sizeof(MIDI) );

  memcpy_P( midi, midi_data, sizeof(MIDI) );
  data_len = swap_l(midi->track.len);
  period = swap_w(midi->header.period);

  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print( period );

  //  Set MIDI baud rate:
  Serial.begin(31250);
//  Serial.begin(38400);

  free( midi );
}

void loop()
{
  unsigned char c;
  unsigned long temp,delta_time,old_time,new_time;

  ptr = (PGM_P)(((MIDI *)midi_data)->track.data);
  old_time = 0;

  while( 1 )
  {
    delta_time = 0;
    c = pgm_read_byte_near(ptr++);
    if( c == 0x00 ) {}
    else
    {
      while( 1 )
      {
        delta_time <<= 7;
        delta_time |= c & 0x7f;
        if( c & 0x80 )
          c = pgm_read_byte_near(ptr++);
        else
          break;
      }
    }

#if 1
    lcd.setCursor(4,1);
    lcd.print( "     " );
    lcd.setCursor(4,1);
    lcd.print( delta_time );
#endif

    if( old_time == 0 )
      new_time = 0;
    else
      new_time = millis();

    temp = (delta_time * 1000 * 10) / period / 35;
    if( temp <= (new_time - old_time) )
      temp = 0;
    else
      temp -= new_time - old_time;

    delay( temp );
    old_time = new_time;

    if( event() == (-1) )
    {
      delay( 10000UL );
      break;
    }
  }
}

int event()
{
  unsigned char c;
  int ret = 0;
  
  c = pgm_read_byte_near(ptr++);  //
  switch( c & 0xf0 )
  {
    case 0xf0 :
      if( c == 0xff )
        ret = meta();
      else
      {
        if( c == 0xf0 )
        {
          c = pgm_read_byte_near(ptr++);  //
          for( int i = c; i > 0; i-- )
		  {
            c = pgm_read_byte_near(ptr++);  //
		  }
        }
        else
        {
          c = pgm_read_byte_near(ptr++);  //
          for( int i = c; i > 0; i-- )
		  {
            c = pgm_read_byte_near(ptr++);  //
		  }
        }
      }
      break;

    case 0x80 :  // 3bytes pattern
    case 0x90 :  // 3bytes pattern
    case 0xa0 :  // 3bytes pattern
    case 0xb0 :  // 3bytes pattern
    case 0xe0 :  // 3bytes pattern

      lcd.setCursor(8,1);
      lcd.print( "        " );
      lcd.setCursor(8,1);

      Serial.print(c,BYTE);
      lcd.print( c,HEX );
      lcd.print( ":" );

      c = pgm_read_byte_near(ptr++);
      Serial.print(c,BYTE);
      lcd.print( c,HEX );
      lcd.print( ":" );

      c = pgm_read_byte_near(ptr++);
      Serial.print(c,BYTE);
      lcd.print( c,HEX );
      break;

    default :  // 2bytes pattern
      lcd.setCursor(8,1);
      lcd.print( "        " );
      lcd.setCursor(8,1);

      Serial.print(c,BYTE);
      lcd.print( c,HEX );
      lcd.print( ":" );

      c = pgm_read_byte_near(ptr++);
      Serial.print(c,BYTE);
      lcd.print( c,HEX );
      break;
  }

  return ret;
}

int meta()
{
  unsigned char c,len;
  int ret = 0;

  c = pgm_read_byte_near(ptr++);
  switch( c )
  {
    case 0x00 :
      Serial.print(0xff,BYTE);Serial.print(c,BYTE);
      c = pgm_read_byte_near(ptr++);
      Serial.print(c,BYTE);
      break;
    case 0x01 :
    case 0x02 :
    case 0x03 :
    case 0x04 :
    case 0x05 :
    case 0x06 :
      Serial.print(0xff,BYTE);Serial.print(c,BYTE);
      len = pgm_read_byte_near(ptr++);
      Serial.print(len,BYTE);

      lcd.setCursor(0,0);
      lcd.print( "                " );
      lcd.setCursor(0,0);
      for( ;len > 0; len-- )
      {
        c = pgm_read_byte_near(ptr++);
        Serial.print(c, BYTE);
        lcd.print( c );
      }
      break;

    case 0x2f :
      Serial.print(0xff,BYTE);Serial.print(c,BYTE);
      c = pgm_read_byte_near(ptr++);
      Serial.print(c,BYTE);
      ret = (-1);
      break;

    case 0x51 :
    case 0x58 :
    case 0x59 :
      Serial.print(0xff,BYTE);Serial.print(c,BYTE);
      len = pgm_read_byte_near(ptr++);
      Serial.print(len,BYTE);
      for( ;len > 0; len-- )
      {
        c = pgm_read_byte_near(ptr++);
        Serial.print(c, BYTE);
      }
      break;

    default :
      break;
  }

  return ret;
}

static unsigned long swap_l( unsigned char src[] )
{
  unsigned long temp = 0;

  temp += src[0];
  temp <<= 8;
  temp += src[1];
  temp <<= 8;
  temp += src[2];
  temp <<= 8;
  temp += src[3];

  return temp;
}

static unsigned short swap_w( unsigned char src[] )
{
  unsigned short temp = 0;

  temp += src[0];
  temp <<= 8;
  temp += src[1];

  return temp;
}


/* ------------------------------------------------------------------------ */
/* バイナリファイルをCソースファイルに変換するプログラム					*/
/*                                                                          */
/*                                  Copyright (C) 2004- by hamayan			*/
/* ------------------------------------------------------------------------ */
#include <stdio.h>
#include <string.h>
#include <time.h>

/* ------------------------------------------------------------------------ */
/* メインね!																*/
/* ------------------------------------------------------------------------ */
int main( int argc, char *argv[] )
{
	char	str[32];
	int		i,c;
	long	length;
	FILE	*in,*out;
	time_t	timer;
	struct	tm	*tblock;

	if( argc != 3 )
	{
		fprintf( stderr, "Argument Missmatch.\r\n" );
		return EOF;
	}

	if( (in = fopen( argv[1], "rb" )) == NULL )
	{
		fprintf( stderr, "Image File Open Error.\r\n" );
		return EOF;
	}
	if( (out = fopen( argv[2], "wb" )) == NULL )
	{
		fprintf( stderr, "Output File Open Error.\r\n" );
		fclose( in );
		return EOF;
	}

	/*ヘッダー部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/* Binary data file convert to C source file program.                       */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	/*ヘッダーファイルの取り込み*/
	fprintf( out, "#include\t<avr/pgmspace.h>\r\n" );

	/*変換後のデータ表現*/
	fprintf( out, "const unsigned char PROGMEM midi_data[] =\r\n" );
	fprintf( out, "{\r\n" );
	do
	{
		fprintf( out, "\t" );
		for( i = 0; i < 16; i++ )
		{
			if( (c = fgetc( in )) == EOF ) break;
			fprintf( out, "0x%02X,", c );
		}
		fprintf( out, "\r\n" );
	} while( c != EOF );
	fprintf( out, "};\r\n\r\n" );

	/*フッター部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	fclose( in );
	fclose( out );

	return 0;
}

/* ------------------------------------------------------------------------ */
/*                                  Copyright (C) 2004- by hamayan			*/
/* ------------------------------------------------------------------------ */


Japaninoで超音波距離計を作ってみる。Maruduinoまたは(◎)の回路図公開 [ATmarquino Arduino]

Image5.pngPDF版回路図はここからダウンロードします。
例によってローカルにダウンロード後、拡張子をpdfに修正してお使いください。
※スケッチと動作している様子は以下のリンク先をご覧ください。
http://hamayan.blog.so-net.ne.jp/2010-05-19

Arduinoのtoneライブラリを使って40KHzの搬送波を生成します。生成した搬送波はArduinoからの出力のままでは5Vpしかありませんので、増幅する為にRS232CドライバーICを利用します。これだと10Vp以上の振幅にする事ができますので、その出力を送信モジュールに入力します。
この振幅を大きくする回路は、トランジスタ技術2010年3月号別冊付録の中の回路を参考とさせていただきました。

受信センサーは2つのアンプで増幅された後、ダイオードで検波されます。超音波を受信するとコンパレータの非反転入力端子に入力する信号がGNDレベルから山が立ち上がりますので、それをオペアンプで構成したコンパレータで検出します。

と、この検出した変化点をArduino側でポーリングで見付け、送信時間から往復の距離を算出する訳ですね。

ソフトウエア的には、40KHzを搬送波とする送信パルスを短時間だけ送出します。※あまり長いと送出している間に反射して戻ってきてしまう為。但し、短すぎると到達距離自体も短くなってしまう。

この送信の時にも受信センサー側はそのパルスを拾ってしまい誤検出しますので、送信の間だけコンパレータの出力をキャンセルするのがD1のダイオードを通したポートの出力です。HIGHを出力している間、コンパレータはLOWを出力し続けます。
送信パルス送出後は、D1に接続されているDIGITAL5をLOWに落として置きます。

その後ポーリングで立ち上がりを検出し、経過時間を求めます。
但し反射波が検出できないと無限ループとなりかねないので、適当なタイミングでループを抜ける処理も必要ですね。大体3m先の往復時間が約18msなので、それよりちょっと多目の時間で抜けると良いでしょう。

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Japaninoで超音波距離計を作ってみる。Maruduinoまたは(◎)の応用編 [ATmarquino Arduino]

Img_1930_s.jpg
Img_1926_s.jpg
Img_1928_s.jpg
超音波センサーを使ってJapaninoで距離計を実現してみました。
計測した対象物までの距離はLCDにて表示を行っています。
電源電圧は5Vです。送信側の振幅をより大きくする為にRS232ドライバーICを流用しています。
40KHzの発振はArduinoのtoneライブラリを使用して発生しています。これを搬送波とする短いパルスを発し、帰って来るまでの時間を計測し、音速≒340m/sから対象物までの距離を計算しています。
音速は周囲温度に依存しますので、実際には温度を計測しながら距離の計算を行うと、もっと良いでしょう。

という訳で簡単なコードを書いておきます。あまり深く考えて記述した物ではないのでご注意を。


#include <LiquidCrystal.h>
#include <avr/io.h>
#include <avr/interrupt.h>

/*************************************************************************/
/* defines                                                               */
/*************************************************************************/
#define  AREF     0
#define  NOT_GND  1
#define  DI13     2
#define  DI12     3
#define  DI11     4
#define  DI10     5
#define  DI9      6
#define  DI8      7
#define  DI7      8
#define  DI6      9
#define  DI5      10
#define  DI4      11
#define  DI3      12
#define  DI2      13
#define  DI1      
#define  DI0      
#define  AN0      14
#define  AN1      15
#define  AN2      16
#define  AN3      17
#define  AN4      18
#define  AN5      19
#define  PWM11    DI4
#define  PWM10    DI5
#define  PWM9     DI6
#define  PWM6     DI9
#define  PWM5     DI10
#define  PWM3     DI12

/*************************************************************************/
/*  global parameter                                                     */
/*************************************************************************/
#define  UltraSonicPin  PWM6
LiquidCrystal lcd(DI2, DI3, DI4, DI5, DI6, DI7);

/*************************************************************************/
/*  prototype                                                            */
/*************************************************************************/

/*************************************************************************/
/*  timer1 output compare match a int handler                            */
/*************************************************************************/
SIGNAL( TIMER1_COMPA_vect )
{
}

/*************************************************************************/
/*  setup                                                                */
/*************************************************************************/
void setup()
{
  lcd.begin(16,2);
  lcd.clear();
  lcd.print( "designed by" );
  lcd.setCursor(0,1);
  lcd.print( "  hamayan." );
  pinMode( DI8, INPUT );
  pinMode( DI10, OUTPUT );
  digitalWrite( DI10, LOW );
}

/*************************************************************************/
/*  main loop                                                            */
/*************************************************************************/
void loop()
{
  digitalWrite( DI10, HIGH );
  tone( UltraSonicPin, 40000 );
  unsigned long startMicro = micros();
  delayMicroseconds( 500 / 8 );
  noTone( UltraSonicPin );
  delayMicroseconds( 500 / 8 );
  digitalWrite( DI10, LOW );
  unsigned long endMicro = startMicro;
  while( digitalRead( DI8 ) == LOW )
  {
    endMicro = micros();
    if( (endMicro - startMicro) > 20 * 1000UL ) break;
  }

  unsigned long distance;
  if( (endMicro - startMicro) < 20 * 1000UL )
  {
    distance = ((340 * (endMicro - startMicro)) / 10000UL) / 2;
  }
  else
  {
    distance = 999;
  }

  lcd.clear();
  lcd.print( distance );
  lcd.print( "cm" );

  delay( 500 );  
}


Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Arduino実験ボード Maruduino、略して(◎)とJapanino [ATmarquino Arduino]

IMG_1921.JPGさっそくMaruduino上でJapaninoを動かしてみました。

これが(◎)の基本構成に最も近い写真かな。左上がArduino、左下にシールド、右上にLCD、右下にはブレッドボードを配置します。



それはそれとして、以下の2枚の写真は、ESEC中にディジインターナショナルさんのブースで展示していた様子です。
Img_1917.jpg


Img_1918.jpg

Arduino実験ボード Maruduino、略して(◎)の資料を公開します。 [ATmarquino Arduino]

※MTM05でP板.COMさんのブースで展示予定です。

※ArduinoではなくRTOS(HOS-V4)のデモも考えて見ます。

※クリエイティブコモンズに基づき、データの公開を始めます。

※Google Docsに部品表を掲載してみました。まあちっと正しく設定できているか判らないので、できれば読めた/読めないをご連絡ください。
https://spreadsheets.google.com/ccc?key=0Ar-X1iewnkZidENlc0lYMS02SlFfeVRDYlg1Qnc2Y1E&hl=ja
一番最初のシートの「オプション」の項目は、基本セットに機能を追加する際に必要となる部品で、スプレッドシートを開いてしばらくすると一番下にシート選択のTABが出てきます。

※さて、回路図のpdfはどうしたものかな。

※ソースとかはやっぱりGoogle Codeが良いのかな。

※6ピン、10ピン、14ピンのシングルラインソケットヘッダーは秋葉原をうろうろしていれば見付かるが、意外と8ピンは見付からないよね。ためしに4ピンを直列にしてみたけれどイマイチだった。一応マルツさんにも探してもらってはいるけれど。

回路図などはここ
シルク図はここ
からダウンロードできます。ただしblogに無理矢理貼り付ける関係上、拡張子がjpgとなっています。
ご自分のパソコンにダウンロード後、回路図はzipに、シルク図はpdfに拡張子を変更してください。

このblogでも何度か(◎)基板の応用例を紹介していますが、
http://hamayan.blog.so-net.ne.jp/2010-05-12
http://hamayan.blog.so-net.ne.jp/2010-04-22

基本的にはこの様な派手な使い方ではなく、動画の7SEG LEDやスイッチが搭載されているところに横長のブレッドボードを置いて、Arduinoを使って色々実験してみようと言う企画で作成した基板です。

ソフトウエアは今のところグダグダなものしか無いので、もう少し人に見せられるようになってから公開を開始します。

回路図パッケージにはCadlus-Xのデータが含まれています。
このデータをP板に提出すれば同じ基板をご自分で作成できます。
CADデータがあるのでご自分で編集も可能ですが、但しその場合、著作権表記代わりの「designed by hamayan」は改竄しないでくださいね。

基板と部品は、マルツさんに販売してもらう予定です。

あと、このページも順次更新します。

小林さんの新刊ではArduinoとブレッドボードを使って、様々な実験を行います。

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本




Making Things Talk ―Arduinoで作る「会話」するモノたち

Making Things Talk ―Arduinoで作る「会話」するモノたち

  • 作者: Tom Igoe
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2008/11/17
  • メディア: 大型本



「オープンソースハードウェアセミナーVol1」レポート Arduino WEBサーバー 新しいWEBサーバースケッチ [ATmarquino Arduino]

ether_shield_018.png昨日は家に帰ってからもう眠くて、眠くて。
今から公開です。

※ほんのちょっとの改造ですが、それでもオリジナルのコンテンツを追加するベースにはなるんじゃないかと思います。
もう少し動作検証して、最終的にはライブラリ化した方が良さそうですね。


ちょっとの間だけArduino WEBサーバーに接続できるようにしておきます。
多分下に写真が掲載されている時は
接続可能です。
http://hamayan.ddo.jp:8888/

ファイルシステムがある訳ではないので、
  {
    {"/",           IndexHtml, 0},
    {"/index.html", IndexHtml, 0},
    {"/index.htm",  IndexHtml, 0},
    {"/chobi_01.jpg", StaticContents, &chobi_01_jpg },
  };

の中でuriとどんどん比較しているだけです。むしろファイルシステムから引っ張ってくるより簡単だと思います。
比較uri文字列の次はユーザー関数の先頭アドレスを入れ、その次のパラメーターはユーザー関数に引き渡したいパラメーターを登録しておきます。
例えば関数StaticContentsは引数の内容を返信する関数です。

このサーバーでは”HTTP1.0”と答えているのでブラウザ側も毎回コネクションを解除する事を想定しており、最初のコネクションの返信ではhtml文章の中に含まれるイメージへのリンクを認識し、そこでもう一回コネクションを張ってイメージコンテンツの取得を行っています。
”HTTP1.1”の”KEEP ALIVE”に比べれば効率が落ちますが、だからと言って元々のArduinoのEthernetライブラリ自体が同時に複数コネクションを張れるようにはなっていない(※KEEP ALIVE中は確か30秒程の時間待ち処理が入るので、その間は別の所からの要求に答えられなくなる。)ので、”HTTP1.0”で動作する方が現実的でしょう。
/****************************************************************/
/* Web Serverで色々いじってみる計画                             */
/*                  Copyright (c) せくすぃ部長 since 2009/06/13 */
/****************************************************************/

/****************************************************************/
/* file include                                                 */
/****************************************************************/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <Ethernet.h>
#include <avr/pgmspace.h>
#include "chobi_01.h"

/****************************************************************/
/* 色々定義                                                     */
/****************************************************************/
#define  LINE_STRING_SIZE  128

enum HTTP_METHOD_TYPE
{
  METHOD_TYPE_IS_GET = 1,
  METHOD_TYPE_IS_HEAD,
  METHOD_TYPE_IS_PUT,
  METHOD_TYPE_IS_POST,
  METHOD_TYPE_IS_DELETE,
  METHOD_TYPE_IS_LINK,
  METHOD_TYPE_IS_UNLINK,
};

/****************************************************************/
/* 大域変数領域                                                 */
/****************************************************************/
char *line;
char meth[10],uri[30],ver[20];
long access_count;

const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
const byte ip[] = { 192, 168, 100, 177 };
const byte gateway[] = { 192, 168, 100, 1 };

/****************************************************************/
/* サーバーレスポンスの固定メッセージ                           */
/****************************************************************/
const char PROGMEM http_ver_and_server_type[] =
  "HTTP/1.0 200 OK\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n";

const char PROGMEM mime_type_txt[] =
  "Content-Type: text/html; charset=UTF-8\r\n\r\n";

const char PROGMEM mime_type_img_jpeg[] =
  "Content-Type: image/JPEG\r\n\r\n";

const char PROGMEM mime_type_img_gif[] =
  "Content-Type: image/gif\r\n\r\n";

const char PROGMEM mime_type_img_png[] =
  "Content-Type: image/png\r\n\r\n";

const char PROGMEM mime_type_img_bmp[] =
  "Content-Type: image/bmp\r\n\r\n";

/****************************************************************/
/* HTTPフレーム                                                 */
/****************************************************************/
const char PROGMEM http_head[] =
  "<html lang=\"ja\"><head>\r\n" \
  "<meta HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=UTF-8\">\r\n" \
  "<title>Arduino WEB Server 0.2</title></head>\r\n" \
  "<body bgcolor=\"#ccffcc\">\r\n";

const char PROGMEM thanks[] =
  "<h3>designed by hamayan</h3>\r\n" \
  "<img src=\"./chobi_01.jpg\" align=\"center\"><br>\r\n" \
  "アクセス有難うございます。このページはArduino+Ether Shieldで表示しています。<br>\r\n" \
  "現在はリクエストのパーサーを作成しています。<br>\r\n";

const char PROGMEM links[] =
  "hamayan blog <a href=\"http://hamayan.blog.so-net.ne.jp/\">http://hamayan.blog.so-net.ne.jp/</a><br>\r\n" \
  "chip 1 stop <a href=\"http://www.chip1stop.com/\">http://www.chip1stop.com/</a><br>\r\n" \
  "オープンソースハードウェアセミナーのページ <a href=\"http://www.chip1stop.com/knowledge/Arduino/\">http://www.chip1stop.com/knowledge/Arduino/</a><br>\r\n" \
  "Make:Japan <a href=\"http://jp.makezine.com/blog/\">http://jp.makezine.com/blog/</a><br><br>\r\n";

const char PROGMEM banner_01[] =
  "<p><a href=\"http://www.chip1stop.com/knowledge/Arduino/\">" \
  "<img src=\"http://www.chip1stop.com/img/link_Arduino.gif\" width=\"468\" height=\"60\" alt=\"Arduinoモニタープログラム参加中\" /></a><br>" \
  "<a href=\"http://www.chip1stop.com/\" title=\"電子部品・半導体の通販サイト - チップワンストップ\">電子部品・半導体の通販サイト - チップワンストップ</a></p><br><br>\r\n";

const char PROGMEM http_foot[] =
  "</body></html>\r\n\r\n";

const char PROGMEM HtmlRes400[] =
{
  "HTTP/1.0 400 Bad Request\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>400 Bad Request</title></head>\r\n" \
  "<h1>Bad Request</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

const char PROGMEM HtmlRes404[] =
{
  "HTTP/1.0 404 Not Found\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>404 Not Found</title></head>\r\n" \
  "<h1>Not Found</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

const char PROGMEM HtmlRes405[] =
{
  "HTTP/1.0 405 Method Not Allowed\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>405 Method Not Allowed</title></head>\r\n" \
  "<h1>Method Not Allowed</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

const char PROGMEM hello[] =
  "<html><body><h1>hello world</h1><br><a href=\"./index.html\">戻る</a></body></html>";

Server server( 8888 );

/****************************************************************/
/* setup                                                        */
/****************************************************************/
void setup()
{
  Ethernet.begin( (uint8_t *)mac, (uint8_t *)ip, (uint8_t *)gateway );
  server.begin();
  Serial.begin( 38400 );
  line = (char *)malloc( LINE_STRING_SIZE );
}
/****************************************************************/
/* loop                                                         */
/****************************************************************/
void loop()
{
  Client client = server.available();

  if( client )
  {
    while( client.connected() )
    {
      char *dst = HTTPGets( client, line, LINE_STRING_SIZE );
      char *argv[ 10 ];
      int div_num = split( dst, argv, sizeof(argv) / sizeof(argv[0]) );  /*文字列分割*/
      strncpy( meth, argv[ 0 ], sizeof(meth) );
      strncpy( uri, argv[ 1 ], sizeof(uri) );
      strncpy( ver, argv[ 2 ], sizeof(ver) );
      break;
    }

    while( client.connected() )
    {
      char *dst = HTTPGets( client, line, LINE_STRING_SIZE );
      if( dst != NULL && *dst == '\0' )  /*改行のみの行を検出*/
      {
        server_response( client, meth, uri );
        break;
      }
    }

//    delay( 1 );
    client.stop();
  }
}

/****************************************************************/
/* 一行取得                                                     */
/* HTTPプロトコルでは行末はCR、LFであると言う前提がある         */
/****************************************************************/
static char *HTTPGets( Client client, char *dst, int size )
{
  int loop;
  char c,*ptr,*limit;

  ptr = dst;
  limit = dst + size;

  for( loop = 10; loop > 0; loop-- )
  {
    if( ptr == limit ) return (char *)0;  /*上限の確認*/

    if( client.available() )
    {
      loop = 10;  /*タイムアウト延長*/

      c = client.read();  /*一文字取得*/

      if( c == '\r' )  /*CRはNULLに変換*/
      {
        *ptr++ = '\0';
      }
      else if( c == '\n' )  /*LFは終端文字*/
      {
        *ptr = '\0';
        return dst;
      }
      else  /*文字の取得*/
      {
        *ptr++ = c;
      }
    }
    else
    {
      delay( 100 );  /*残りのデータが遅れて来る可能性があるので、ここで待ちを入れる*/
    }
  }

  return (char *)0;
}

/****************************************************************/
/* 文字列分割ユーティリティ                                     */
/****************************************************************/
static int split( char *str , char *argv[], int sz )
{
  int argc = 0;

  while( *str != '\0' && argc < sz )
  {
    if( isgraph( *str ) != 0 )
    {
      argv[ argc++ ] = str;
      while( *str != '\0' && isgraph( *str ) != 0 ) str++;
    }
    else *str++ = '\0';
  }

  return argc;
}

/****************************************************************/
/* サーバー側の応答処理                                         */
/****************************************************************/
void server_response( Client client, char *method, char *uri )
{
  int meth;
  static const struct COMMAND_LIST
  {
    void ( PROGMEM *fn )( Client client, char *uri );
    char PROGMEM *meth_name;
  } list[] =
  {
    { Method_GET, "GET" },
    { Method_HEAD, "HEAD" },
    { Method_PUT, "PUT" },
    { Method_POST, "POST" },
    { Method_DELETE, "DELETE" },
    { Method_LINK, "LINK" },
    { Method_UNLINK, "UNLINK" },
  };

  for( meth = 0; meth < sizeof( list ) / sizeof( list[0] ); meth++ )
  {
    /*メソッド文字列の比較を行い、該当するメソッドが見つかれば実行する*/
    if( strncmp( method, list[ meth ].meth_name, strlen( list[ meth ].meth_name ) ) == 0 )
    {
      list[ meth ].fn( client, uri );
      break;
    }
  }
  if( meth == sizeof( list ) / sizeof( list[0] ) )
  {
    Bad_Request( client );
  }
}

/****************************************************************/
/* METHOD GET                                                   */
/****************************************************************/
static void Method_GET( Client client, char *uri )
{
  int req;
  struct URL_LIST
  {
    char PROGMEM *name;
    void ( PROGMEM *fn )( Client client, char *uri, const FILE_PROPERTIES *pro );
    const FILE_PROPERTIES *property;
  } PROGMEM list[] =
  {
    {"/",           IndexHtml, 0},
    {"/index.html", IndexHtml, 0},
    {"/index.htm",  IndexHtml, 0},
    {"/chobi_01.jpg", StaticContents, &chobi_01_jpg },
  };

  for( req = 0; req < sizeof( list ) / sizeof( list[0] ); req++ )
  {
    /*uriの比較を行い、該当するuriが見つかれば実行する*/
    if( strcmp( uri, list[ req ].name ) == 0 )
    {
      list[ req ].fn( client, uri, list[ req ].property );
      break;
    }
  }
  if( req == sizeof( list ) / sizeof( list[0] ) )
  {
    /*要求されたuriが見付からなかった時*/
    client.write_P( HtmlRes404, sizeof( HtmlRes404 ) - 1 );
    return;
  }
}

/****************************************************************/
/* METHOD HEAD                                                  */
/****************************************************************/
static void Method_HEAD( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD PUT                                                   */
/****************************************************************/
static void Method_PUT( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD POST                                                  */
/****************************************************************/
static void Method_POST( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD DELETE                                                */
/****************************************************************/
static void Method_DELETE( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD LINK                                                  */
/****************************************************************/
static void Method_LINK( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD UNLINK                                                */
/****************************************************************/
static void Method_UNLINK( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* BAD REQUEST                                                  */
/****************************************************************/
static void Bad_Request( Client client )
{
  client.write_P( HtmlRes400, sizeof( HtmlRes400 ) - 1 );
}

/****************************************************************/
/* index.htmlの返信を行う                                       */
/****************************************************************/
static void IndexHtml( Client client, char *uri, const FILE_PROPERTIES *pro )
{
  //レスポンスヘッダーの返信
  client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
  client.write_P( mime_type_txt, sizeof( mime_type_txt ) - 1 );

  //httpヘッダーの返信
  client.write_P( http_head, sizeof( http_head ) - 1 );

  //サンキューメッセージ
  client.write_P( thanks, sizeof( thanks ) - 1 );

  //リンク
  client.write_P( links, sizeof( links ) - 1 );

  //Arduinoバージョン
  sprintf( line, "Arduino ver=%d <br>\r\n", ARDUINO );
  client.write( line );

  //アクセスカウント
  sprintf( line, "COUNT=%d <br>\r\n", ++access_count );
  client.write( line );

  //バナー
  client.write_P( banner_01, sizeof( banner_01 ) - 1 );

  //Footer
  client.write_P( http_foot, sizeof( http_foot ) - 1 );
}

/****************************************************************/
/* 静的コンテンツ(FILE)の返信を行う                           */
/****************************************************************/
static void StaticContents( Client client, char *uri, const FILE_PROPERTIES *pro )
{
  //レスポンスヘッダーの返信
  switch( pro->attr )
  {
    case AddType_TXT :
  //レスポンスヘッダーの返信
      client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
      client.write_P( mime_type_txt, sizeof( mime_type_txt ) - 1 );
      break;

    case AddType_JPEG :
      client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
      client.write_P( mime_type_img_jpeg, sizeof( mime_type_img_jpeg ) - 1 );
      break;

    case AddType_GIF :
      client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
      client.write_P( mime_type_img_gif, sizeof( mime_type_img_gif ) - 1 );
      break;

    case AddType_PNG :
      client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
      client.write_P( mime_type_img_png, sizeof( mime_type_img_png ) - 1 );
      break;

    case AddType_BMP :
      client.write_P( http_ver_and_server_type, sizeof( http_ver_and_server_type ) - 1 );
      client.write_P( mime_type_img_bmp, sizeof( mime_type_img_bmp ) - 1 );
      break;

    case AddType_APPLI :
    case AddType_AUDIO :
    case AddType_VIDEO :
    default :
      return;
  }

  //静的コンテンツの返信
  client.write_P( pro->file, pro->size );
}


chobi_01.hの中身
/* ------------------------------------------------------------------------ */
/* Binary data file convert to header file program.                         */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */
#include  <avr/pgmspace.h>
#include  "mime.h"

extern const FILE_PROPERTIES chobi_01_jpg;

/* ------------------------------------------------------------------------ */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */


mime.hの中身
/* ------------------------------------------------------------------------ */
/*  Memi Typeの定義                                                         */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */

enum HTTP_ADD_TYPE
{
  AddHandler,     /*ハンドラ*/
  AddType_TXT,    /*テキスト*/
  AddType_JPEG,   /*JPEGイメージ*/
  AddType_GIF,    /*GIFイメージ*/
  AddType_PNG,    /*PNGイメージ*/
  AddType_BMP,    /*BMPイメージ*/
  AddType_APPLI,  /*アプリケーション*/
  AddType_AUDIO,  /*audio*/
  AddType_VIDEO,  /*video*/
};

typedef struct
{
	char	*filename;	/*ファイル名*/
	char	*timestamp;	/*タイムスタンプ*/
	int		attr;	    /*属性*/
	const unsigned char PROGMEM	*file;		/*ファイルの開始アドレス*/
	char	*author;	/*著者*/
	void	*certification;	/*認証用*/
	long	size;		/*ファイルののサイズ*/
} FILE_PROPERTIES;

/* ------------------------------------------------------------------------ */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */


Arduinoモニタープログラム参加中
電子部品・半導体の通販サイト - チップワンストップ




マスタリングTCP/IP 入門編 第4版

マスタリングTCP/IP 入門編 第4版

  • 作者: 竹下 隆史
  • 出版社/メーカー: オーム社
  • 発売日: 2007/02/24
  • メディア: 大型本



「オープンソースハードウェアセミナーVol1」レポート Arduino WEBサーバー 静的コンテンツ用バイナリー to Cソース変換プログラムのソース [ATmarquino Arduino]

ether_shield_018.png下手なプログラムで申し訳ない。
でも、これ見ただけでは何の事か判らないですね、、、。


例えばこんな写真を
chobi_01.jpg


通すと一番下のコードを出力します。ちなみに写真のデータサイズは12Kbyte程度でした。

作成したプログラムはコマンドラインで動かします。GUIのプログラムは苦手で。

※もうこんな時間なので、この静的コンテンツを使ったスケッチの方は次回公開します。
/* ------------------------------------------------------------------------ */
/* バイナリファイルをCソースファイルに変換するプログラム					*/
/*                                                                          */
/*                                  Copyright (C) 2004- by hamayan			*/
/*                                  hamayan.contact あと 爺mail.com         */
/* ------------------------------------------------------------------------ */
#include <stdio.h>
#include <string.h>
#include <time.h>

/* ------------------------------------------------------------------------ */
/* メインね!																*/
/* ------------------------------------------------------------------------ */
int main( int argc, char *argv[] )
{
	char	str[ 32 ],header_file[ 32 ];
	int		i,c;
	long	length;
	FILE	*in,*out;
	time_t	timer;
	struct	tm	*tblock;

	if( argc != 3 )
	{
		fprintf( stderr, "Argument Missmatch.\r\n" );
		return EOF;
	}

	if( (in = fopen( argv[1], "rb" )) == NULL )
	{
		fprintf( stderr, "Image File Open Error.\r\n" );
		return EOF;
	}
	if( (out = fopen( argv[2], "wb" )) == NULL )
	{
		fprintf( stderr, "Output File Open Error.\r\n" );
		fclose( in );
		return EOF;
	}

	/*ヘッダー部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/* Binary data file convert to C source file program.                       */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/*                                        hamayan.contact あと 爺mail.com   */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	/*ヘッダーファイルの取り込み*/
	fprintf( out, "#include  <avr/pgmspace.h>\r\n" );
	fprintf( out, "#include  \"mime.h\"\r\n\r\n" );

	/*変換後のデータ表現*/
	fprintf( out, "static const unsigned char PROGMEM file[] =\r\n" );
	fprintf( out, "{\r\n" );
	do
	{
		fprintf( out, "\t" );
		for( i = 0; i < 16; i++ )
		{
			if( (c = fgetc( in )) == EOF ) break;
			fprintf( out, "0x%02X,", c );
		}
		fprintf( out, "\r\n" );
	} while( c != EOF );
	fprintf( out, "};\r\n\r\n" );

	/*プロパティシートを生成する。*/
	strcpy( str, argv[1] );
	*( strchr( str, '.' ) ) = '_';
	fprintf( out, "const FILE_PROPERTIES %s =\r\n", str );
	fprintf( out, "{\r\n" );

		/*ファイル名*/
		fprintf( out, "\t\"%s\",\t/*ファイル名*/\r\n",
		  argv[1] );

		/*タイムスタンプ*/
		timer = time(NULL);
		tblock = localtime(&timer);
		fprintf( out, "\t\"%4u/%2u/%2u %2u:%2u:%2u\",\t/*タイムスタンプ*/\r\n",
		  tblock->tm_year + 1900,
		  tblock->tm_mon + 1,
		  tblock->tm_mday,
		  tblock->tm_hour,
		  tblock->tm_min,
		  tblock->tm_sec );

		/*Mime type*/
		fprintf( out, "\t%s,\t/*Mime type*/\r\n",
		 (strcmp( "htm", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "HTM", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "html", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "HTML", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "txt", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "TXT", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "log", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "LOG", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_TXT" : 
		 (strcmp( "jpg", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_JPEG" : 
		 (strcmp( "JPG", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_JPEG" : 
		 (strcmp( "jpeg", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_JPEG" : 
		 (strcmp( "JPEG", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_JPEG" : 
		 (strcmp( "gif", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_GIF" : 
		 (strcmp( "GIF", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_GIF" : 
		 (strcmp( "png", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_PNG" : 
		 (strcmp( "PNG", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_PNG" : 
		 (strcmp( "bmp", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_BMP" : 
		 (strcmp( "BMP", strchr( argv[1], '.' ) + 1) == 0) ? "AddType_BMP" : ""
		);

		/*ファイルの開始アドレス*/
		fprintf( out, "\tfile,\t/*ファイルの開始アドレス*/\r\n" );

		/*著者*/
		fprintf( out, "\t\"\",\t/*著者*/\r\n" );

		/*認証用*/
		fprintf( out, "\t(void *)0,\t/*認証用*/\r\n" );

		/*ファイルののサイズ*/
		fseek( in, 0L, SEEK_END );
		length = ftell( in );
		rewind( in );
		fprintf( out, "\t%ldU\t/*ファイルのサイズ*/\r\n", length );
	fprintf( out, "};\r\n\r\n" );

	*(strchr( argv[1], '.' )) = '\0';

	/*フッター部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/*                                        hamayan.contact あと 爺mail.com   */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	fclose( in );
	fclose( out );

	/*ヘッダーファイルの出力*/
	strcpy( header_file, argv[2] );
	strcpy( strchr( header_file, '.' ), ".h" );


	if( (out = fopen( header_file, "wb" )) == NULL )
	{
		fprintf( stderr, "Output File Open Error.\r\n" );
		fclose( in );
		return EOF;
	}

	/*ヘッダー部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/* Binary data file convert to header file program.                         */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/*                                        hamayan.contact あと 爺mail.com   */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	/*ヘッダーファイルの取り込み*/
	fprintf( out, "#include  <avr/pgmspace.h>\r\n" );
	fprintf( out, "#include  \"mime.h\"\r\n\r\n" );

	/**/
	fprintf( out, "extern const FILE_PROPERTIES %s;\r\n\r\n", str );

	/*フッター部の出力*/
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );
	fprintf( out, "/*                                             designed by hamayan          */\r\n" );
	fprintf( out, "/*                                             Copyright(C) hamayan         */\r\n" );
	fprintf( out, "/*                                             since 2004 -                 */\r\n" );
	fprintf( out, "/*                                        hamayan.contact あと 爺mail.com   */\r\n" );
	fprintf( out, "/* ------------------------------------------------------------------------ */\r\n" );

	fclose( out );
	return 0;
}

/* ------------------------------------------------------------------------ */
/*                                  Copyright (C) 2004- by hamayan			*/
/*                                  hamayan.contact あと 爺mail.com         */
/* ------------------------------------------------------------------------ */


ちょびちゃんのCソース化
/* ------------------------------------------------------------------------ */
/* Binary data file convert to C source file program.                       */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */
#include  <avr/pgmspace.h>
#include  "mime.h"

static const unsigned char PROGMEM file[] =
{
	0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x00,0x48,

  長いので途中省略

	0xE0,0xFA,0xFA,0x83,0x45,0x4D,0xE3,0xD9,0x64,0xDF,0xB7,0x79,0xC1,0x19,0xA2,0xAD,
	0x23,0x29,0x3B,0x1F,0xFF,0xD9,
};

const FILE_PROPERTIES chobi_01_jpg =
{
	"chobi_01.jpg",	/*ファイル名*/
	"2009/ 6/19  2:10:59",	/*タイムスタンプ*/
	AddType_JPEG,	/*Mime type*/
	file,	/*ファイルの開始アドレス*/
	"",	/*著者*/
	(void *)0,	/*認証用*/
	12358U	/*ファイルのサイズ*/
};

/* ------------------------------------------------------------------------ */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */

ちょびちゃんのヘッダーファイル
/* ------------------------------------------------------------------------ */
/* Binary data file convert to header file program.                         */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */
#include  <avr/pgmspace.h>
#include  "mime.h"

extern const FILE_PROPERTIES chobi_01_jpg;

/* ------------------------------------------------------------------------ */
/*                                             designed by hamayan          */
/*                                             Copyright(C) hamayan         */
/*                                             since 2004 -                 */
/*                                        hamayan.contact あと 爺mail.com   */
/* ------------------------------------------------------------------------ */

Arduinoモニタープログラム参加中
電子部品・半導体の通販サイト - チップワンストップ




Arduinoをはじめよう

Arduinoをはじめよう

  • 作者: Massimo Banzi
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/03/27
  • メディア: 単行本(ソフトカバー)



Making Things Talk -Arduinoで作る「会話」するモノたち

Making Things Talk -Arduinoで作る「会話」するモノたち

  • 作者: Tom Igoe
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2008/11/17
  • メディア: 大型本



「オープンソースハードウェアセミナーVol1」レポート Arduino WEBサーバー リクエストの解析をちょっと始める [ATmarquino Arduino]

※なんかイマイチなんで、近日中に書き直すつもり。

Img_1427.jpg表示している内容は変わらないのだけれど、処理が随分機能アップしています、、、嘘!する予定。

GET Methodの解析、uriの解析、Mimeタイプの解析はもう疲れて適当に終了。


/****************************************************************/
/* Web Serverで色々いじってみる計画                             */
/*                  Copyright (c) せくすぃ部長 since 2009/06/13 */
/****************************************************************/

/****************************************************************/
/* file include                                                 */
/****************************************************************/
#include <Ethernet.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/pgmspace.h>

/****************************************************************/
/* 色々定義                                                     */
/****************************************************************/
#define  LINE_STRING_SIZE  128

enum HTTP_METHOD_TYPE
{
  METHOD_TYPE_IS_GET = 1,
  METHOD_TYPE_IS_HEAD,
  METHOD_TYPE_IS_PUT,
  METHOD_TYPE_IS_POST,
  METHOD_TYPE_IS_DELETE,
  METHOD_TYPE_IS_LINK,
  METHOD_TYPE_IS_UNLINK,
};

enum HTTP_ADD_TYPE
{
  AddHandler,     /*ハンドラ*/
  AddType_TXT,    /*テキスト*/
  AddType_IMAGE,  /*イメージ*/
  AddType_APPLI,  /*アプリケーション*/
  AddType_AUDIO,  /*audio*/
  AddType_VIDEO,  /*video*/
};

/****************************************************************/
/* 大域変数領域                                                 */
/****************************************************************/
char *line;
char meth[10],uri[30],ver[20];
long access_count;

const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
const byte ip[] = { 192, 168, 1, 177 };
const byte gateway[] = { 192, 168, 1, 1 };

/****************************************************************/
/* サーバーレスポンスの固定メッセージ                           */
/****************************************************************/
const char PROGMEM http_head[] =
  "HTTP/1.0 200 OK\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head>\r\n" \
  "<meta HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=UTF-8\">\r\n" \
  "<title>Arduino WEB Server 0.1</title></head>\r\n" \
  "<body bgcolor=\"#ccffcc\">\r\n";

const char PROGMEM thanks[] =
  "<h3>designed by hamayan</h3>\r\n" \
  "アクセス有難うございます。このページはArduino+Ether Shieldで表示しています。<br>\r\n" \
  "現在はリクエストのパーサーを作成しています。<br>\r\n";

const char PROGMEM links[] =
  "hamayan blog <a href=\"http://hamayan.blog.so-net.ne.jp/\">http://hamayan.blog.so-net.ne.jp/</a><br>\r\n" \
  "chip 1 stop <a href=\"http://www.chip1stop.com/\">http://www.chip1stop.com/</a><br>\r\n" \
  "オープンソースハードウェアセミナーのページ <a href=\"http://www.chip1stop.com/knowledge/Arduino/\">http://www.chip1stop.com/knowledge/Arduino/</a><br>\r\n" \
  "Make:Japan <a href=\"http://jp.makezine.com/blog/\">http://jp.makezine.com/blog/</a><br><br>\r\n";

const char PROGMEM banner_01[] =
  "<p><a href=\"http://www.chip1stop.com/knowledge/Arduino/\">" \
  "<img src=\"http://www.chip1stop.com/img/link_Arduino.gif\" width=\"468\" height=\"60\" alt=\"Arduinoモニタープログラム参加中\" /></a><br>" \
  "<a href=\"http://www.chip1stop.com/\" title=\"電子部品・半導体の通販サイト - チップワンストップ\">電子部品・半導体の通販サイト - チップワンストップ</a></p><br><br>\r\n";

const char PROGMEM http_foot[] =
  "</body></html>\r\n\r\n";

const char PROGMEM img_src[] =
  "<p><img src=\"./image2.jpg\" width=\"200\" height=\"140\" align=\"center\"></p><br><br>\r\n";

const char PROGMEM jpeg_head[] =
  "HTTP/1.0 200 OK\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: image/JPEG\r\n\r\n";

const char PROGMEM HtmlRes400[] =
{
  "HTTP/1.0 400 Bad Request\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>400 Bad Request</title></head>\r\n" \
  "<h1>Bad Request</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

const char PROGMEM HtmlRes404[] =
{
  "HTTP/1.0 404 Not Found\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>404 Not Found</title></head>\r\n" \
  "<h1>Not Found</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

const char PROGMEM HtmlRes405[] =
{
  "HTTP/1.0 405 Method Not Allowed\r\n" \
  "Server: Arduino with Ether Shield/ ver.0.2\r\n" \
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" \
  "<html lang=\"ja\"><head><title>405 Method Not Allowed</title></head>\r\n" \
  "<h1>Method Not Allowed</h1>\r\n" \
  "</body></html>\r\n\r\n"
};

Server server( 8888 );

/****************************************************************/
/* setup                                                        */
/****************************************************************/
void setup()
{
  Ethernet.begin( (uint8_t *)mac, (uint8_t *)ip, (uint8_t *)gateway );
  server.begin();
  Serial.begin( 38400 );
  line = (char *)malloc( LINE_STRING_SIZE );
}

/****************************************************************/
/* loop                                                         */
/****************************************************************/
void loop()
{
  Client client = server.available();

  if( client )
  {
    while( client.connected() )
    {
      char *dst = HTTPGets( client, line, LINE_STRING_SIZE );
      char *argv[ 10 ];
      int div_num = split( dst, argv, sizeof(argv) / sizeof(argv[0]) );  /*文字列分割*/
      strncpy( meth, argv[ 0 ], sizeof(meth) );
      strncpy( uri, argv[ 1 ], sizeof(uri) );
      strncpy( ver, argv[ 2 ], sizeof(ver) );
      break;
    }

    while( client.connected() )
    {
      char *dst = HTTPGets( client, line, LINE_STRING_SIZE );
      if( dst != NULL && *dst == '\0' )  /*改行のみの行を検出*/
      {
        server_response( client, meth, uri );
        break;
      }
    }

//    delay( 1 );
    client.stop();
  }
}

/****************************************************************/
/* サーバー側の応答処理                                         */
/****************************************************************/
void server_response( Client client, char *method, char *uri )
{
  int meth;
  static const struct COMMAND_LIST
  {
    void ( PROGMEM *fn )( Client client, char *uri );
    char PROGMEM *meth_name;
  } list[] =
  {
    { Method_GET, "GET" },
    { Method_HEAD, "HEAD" },
    { Method_PUT, "PUT" },
    { Method_POST, "POST" },
    { Method_DELETE, "DELETE" },
    { Method_LINK, "LINK" },
    { Method_UNLINK, "UNLINK" },
  };

  for( meth = 0; meth < sizeof( list ) / sizeof( list[0] ); meth++ )
  {
    /*メソッド文字列の比較を行い、該当するメソッドが見つかれば実行する*/
    if( strncmp( method, list[ meth ].meth_name, strlen( list[ meth ].meth_name ) ) == 0 )
    {
      list[ meth ].fn( client, uri );
      break;
    }
  }
  if( meth == sizeof( list ) / sizeof( list[0] ) )
  {
    Bad_Request( client );
  }
}

/****************************************************************/
/* METHOD GET                                                   */
/****************************************************************/
static void Method_GET( Client client, char *uri )
{
  int req;
  static const struct URL_LIST
  {
    char PROGMEM *name;
    int  PROGMEM type;
    void PROGMEM *property;
  } list[] =
  {
    {"/",           AddType_TXT, 0},
    {"/index.html", AddType_TXT, 0},
    {"/index.htm",  AddType_TXT, 0},
  };

  for( req = 0; req < sizeof( list ) / sizeof( list[0] ); req++ )
  {
    /*uriの比較を行い、該当するuriが見つかれば実行する*/
    if( strcmp( uri, list[ req ].name ) == 0 )
    {
      break;
    }
  }
  if( req == sizeof( list ) / sizeof( list[0] ) )
  {
    /*要求されたuriが見付からなかった時*/
    client.write_P( HtmlRes404, sizeof( HtmlRes404 ) - 1 );
    return;
  }

  switch( list[ req ].type )
  {
    case AddType_TXT :
      Response_Handler( client, uri );
      break;

    case AddHandler :
    case AddType_IMAGE :
    case AddType_APPLI :
    case AddType_AUDIO :
    case AddType_VIDEO :
    default :
      client.write_P( HtmlRes404, sizeof( HtmlRes404 ) - 1 );
      break;
  }
}

/****************************************************************/
/* 応答メッセージの出力                                         */
/****************************************************************/
static void Response_Handler( Client client, char *uri )
{
  if( 1 )  /*今のところ拡張子まで判定していないので、全部同じ動きをさせる*/
  {
    //httpヘッダーの返信
    client.write_P( http_head, sizeof( http_head ) - 1 );

    //サンキューメッセージ
    client.write_P( thanks, sizeof( thanks ) - 1 );

    //リンク
    client.write_P( (const uint8_t *)links, sizeof( links ) - 1 );

    //Arduinoバージョン
    sprintf( line, "Arduino ver=%d <br>\r\n", ARDUINO );
    client.write( line );

    //アクセスカウント
    sprintf( line, "COUNT=%d <br>\r\n", ++access_count );
    client.write( line );

    //バナー
    client.write_P( (const uint8_t *)banner_01, sizeof( banner_01 ) - 1 );

    //Footer
    client.write_P( (const uint8_t *)http_foot, sizeof( http_foot ) - 1 );
  }
}

/****************************************************************/
/* METHOD HEAD                                                  */
/****************************************************************/
static void Method_HEAD( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD PUT                                                   */
/****************************************************************/
static void Method_PUT( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD POST                                                  */
/****************************************************************/
static void Method_POST( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD DELETE                                                */
/****************************************************************/
static void Method_DELETE( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD LINK                                                  */
/****************************************************************/
static void Method_LINK( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* METHOD UNLINK                                                */
/****************************************************************/
static void Method_UNLINK( Client client, char *uri )
{
  /*現在サポートしていないので、許可されていないメソッドとして返信*/
  client.write_P( HtmlRes405, sizeof( HtmlRes405 ) - 1 );
}

/****************************************************************/
/* BAD REQUEST                                                  */
/****************************************************************/
static void Bad_Request( Client client )
{
  client.write_P( HtmlRes400, sizeof( HtmlRes400 ) - 1 );
}

/****************************************************************/
/* 一行取得                                                     */
/* HTTPプロトコルでは行末はCR、LFであると言う前提がある         */
/****************************************************************/
static char *HTTPGets( Client client, char *dst, int size )
{
  int loop;
  char c,*ptr,*limit;

  ptr = dst;
  limit = dst + size;

  for( loop = 10; loop > 0; loop-- )
  {
    if( ptr == limit ) return (char *)0;  /*上限の確認*/

    if( client.available() )
    {
      loop = 10;  /*タイムアウト延長*/

      c = client.read();  /*一文字取得*/

      if( c == '\r' )  /*CRはNULLに変換*/
      {
        *ptr++ = '\0';
      }
      else if( c == '\n' )  /*LFは終端文字*/
      {
        *ptr = '\0';
        return dst;
      }
      else  /*文字の取得*/
      {
        *ptr++ = c;
      }
    }
    else
    {
      delay( 100 );  /*残りのデータが遅れて来る可能性があるので、ここで待ちを入れる*/
    }
  }

  return (char *)0;
}

/****************************************************************/
/* 文字列分割ユーティリティ                                     */
/****************************************************************/
static int split( char *str , char *argv[], int sz )
{
  int argc = 0;

  while( *str != '\0' && argc < sz )
  {
    if( isgraph( *str ) != 0 )
    {
      argv[ argc++ ] = str;
      while( *str != '\0' && isgraph( *str ) != 0 ) str++;
    }
    else *str++ = '\0';
  }

  return argc;
}

/****************************************************************/
/* end of file                                                  */
/*                  Copyright (c) せくすぃ部長 since 2009/06/13 */
/****************************************************************/


Arduinoモニタープログラム参加中
電子部品・半導体の通販サイト - チップワンストップ




マスタリングTCP/IP 入門編 第4版

マスタリングTCP/IP 入門編 第4版

  • 作者: 竹下 隆史
  • 出版社/メーカー: オーム社
  • 発売日: 2007/02/24
  • メディア: 大型本



ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

  • 作者: 戸根 勤
  • 出版社/メーカー: 日経BP社
  • 発売日: 2007/04/12
  • メディア: 単行本(ソフトカバー)



詳解TCP/IP〈Vol.2〉実装

詳解TCP/IP〈Vol.2〉実装

  • 作者: ゲリー・R. ライト
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2002/12
  • メディア: 単行本



前の10件 | - ATmarquino Arduino ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。