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

Arduino IDEでボードマネージャーがエラーを吐くようになった時の対応 [ATmarquino Arduino]

Arduino IDEでボードマネージャーがエラーを吐くようになった時の対応

downloads.arduino/packages/package_index.jsonがダウンロードできない!ってエラーの時の対応、、、
以下のリンク先を参照。
https://github.com/arduino/Arduino/issues/5188

オレの場合は"package_index.json.tmp"が該当した。クソゥ、、、
nice!(0)  コメント(0) 

Arduino AVRでマルチタスクしてみない [ATmarquino Arduino]

avrWaveGenerator_001.png


折角なのでPWMで2相出力してみる。
/**********************************************************/
/* AVR Atmega328P PWM generator                           */
/**********************************************************/
#include <avr/io.h>
#include <FlexiTimer2.h>

extern "C"
{
}

/**********************************************************/
/* prototypes                                             */
/**********************************************************/

/**********************************************************/
/* valiables                                              */
/**********************************************************/
#define  PWMA_PIN  9  // PB1:OC1A
#define  PWMB_PIN  10  // PB2:OC1B
#define  TIMER_COUNTER_CLOCK  (1000000)
#define  FREQUENCY            (50.0f)
#define  RESOLUTION           (32)
#define  PHASE_SHIFT          (-60.0f)

int scale = (256 / 2) - 1;  /**/
int offset = (256 / 2) - 0;  /* center position */
int waveTableCounter;
float channelPhase = (2 * M_PI * PHASE_SHIFT / 360.0f);
unsigned int waveTableA[ RESOLUTION ];
unsigned int waveTableB[ RESOLUTION ];

/**********************************************************/
/* setup                                                  */
/**********************************************************/
void setup()
{
  Serial.begin( 115200UL );
  Serial.println( "AVR Atmega328P PWM generator." );
  pinMode( PWMA_PIN, OUTPUT );
  pinMode( PWMB_PIN, OUTPUT );

  /* generate wave data */
  for( int i = 0; i < RESOLUTION; i++ )
  {
    int tempI = (int)(sin(2 * M_PI * i / RESOLUTION) * scale);
    waveTableA[ i ] = (unsigned int)tempI + offset;
    tempI = (int)(sin((2 * M_PI * i / RESOLUTION) + channelPhase) * scale);
    waveTableB[ i ] = (unsigned int)tempI + offset;
  }

  /* display wave data A */
  Serial.println( "WAVE DATA A" );
  for( int i = 0; i < RESOLUTION; i++ )
  {
    Serial.print( waveTableA[ i ], DEC );
    Serial.print( "," );
    if( (i % 10) == 9 ) Serial.println();
  }
  Serial.println();

  /* display wave data B */
  Serial.println( "WAVE DATA B" );
  for( int i = 0; i < RESOLUTION; i++ )
  {
    Serial.print( waveTableB[ i ], DEC );
    Serial.print( "," );
    if( (i % 10) == 9 ) Serial.println();
  }
  Serial.println();

  /* timer counter initialize. */
  TCCR1B = 0x00;  //  timer1 stop
  TCNT1 = 0x0000;  // 16bit counter clear
  TIMSK1 = 0x00;  // interrupt disable
  TCCR1A = 0b10100001;  //  0b10 10 00 01
    // OC1A : compare match goes OC1A to clear and top goes OC1A to set.
    // OC1B : compare match goes OC1B to clear and top goes OC1B to set.
    // fast 8bit PWM and top is 0x00FF. WGM = 0b0101
  TCCR1B = 0b00001010;  //  0b0 0 0 01 010
    // fast 8bit PWM and top is 0x00FF.
    // clkIO / 8 priscaller.
  OCR1A = waveTableA[ 0 ];
  OCR1B = waveTableB[ 0 ];
  TIMSK1 = 0x00;  // interrupt disable

  waveTableCounter = 1;

  FlexiTimer2::set( 1, 1.0f / (FREQUENCY * RESOLUTION), pwmUpdateHandler );
  FlexiTimer2::start();

  /* Infinite loop */
  while(1) {}
}

/**********************************************************/
/* loop ※使われない                                      */
/**********************************************************/
void loop()
{
}

/**********************************************************/
/* pwm update handler                                     */
/**********************************************************/
void pwmUpdateHandler()
{
  OCR1A = waveTableA[ waveTableCounter ];
  OCR1B = waveTableB[ waveTableCounter ];
  if( ++waveTableCounter >= RESOLUTION )
  {
    waveTableCounter = 0;
  }
}


nice!(0)  コメント(0) 

Arduino AVRでマルチタスクしてみる タスク2 [ATmarquino Arduino]

avrMultiTask_002.png


ファイル名を変えずに中身を書き換えちゃったのは、まずかったかなぁ、、、

マルチタスクのサンプルとして、PWMで50Hzのサイン波を出力するデモ。
別途用意したスイッチを押す度に別途用意したLPFを通してサイン波が出力される。ただし10秒間掛けて波形はフェードアウトする。

/**********************************************************/
/* マルチタスクやってみる                                 */
/* PWMで50hzのサイン波を出力する。10秒掛けてフェードアウト。 */
/**********************************************************/
#include <avr/io.h>
#include <FlexiTimer2.h>
#include "delivertive.h"

extern "C"
{
  #include "mul_tsk.h"
}

/**********************************************************/
/* prototypes                                             */
/**********************************************************/
void tsk_ini( void );
void stackMonitor( void );
void switchScanTask( void );
void pwmGenerateTask( void );

/**********************************************************/
/* valiables                                              */
/**********************************************************/
SYSTIM systim;  // 1msでインクリメントする変数
uint8_t tsk0_stk[ 128 * 1 ];
uint8_t tsk1_stk[ 128 * 1 ];
uint8_t tsk2_stk[ 128 * 1 ];

#define  PWM_PIN      10
#define  TRIGGER_PIN  2
#define  LED_PIN      13

#define  TIMER_COUNTER_CLOCK  (8 * 1000000UL)
#define  PWM_FREQUENCY        (10 * 1000)
#define  RESOLUTION           (40)  /* 50hz * 40 over sampling. */
#define  DELTA_SLOPE          (1.0f / 500)

int scale = TIMER_COUNTER_CLOCK / PWM_FREQUENCY / 2;  /* 1000000 is timer clock */
int offset = TIMER_COUNTER_CLOCK / PWM_FREQUENCY / 2;  /* center position */
int waveTableCounter;
float slope = 1.0f - DELTA_SLOPE;  /* 10s = 20ms * 500 */
int originalWaveTable[ RESOLUTION ];
unsigned int waveTable[ RESOLUTION ];
unsigned char switchScanUpdate;
unsigned long timer1CompbIsrCounter;
bool conversionStart = false;

/**********************************************************/
/* setup                                                  */
/**********************************************************/
void setup()
{
  Serial.begin( 115200UL );
  Serial.println( "AVR Multi Task Demo." );

  /* ststem and pwm update timer start. */
  FlexiTimer2::set( 5, 1.0f / 10000, pwmUpdateHandler );
  FlexiTimer2::start();

  tsk_ini();  //タスクの初期化
  sta_rdq( ID_monitor );  //ラウンドロビン開始。ここからタスクが開始される
}

/**********************************************************/
/* loop ※使われない                                      */
/**********************************************************/
void loop()
{
}

/**********************************************************/
/* タスク初期化                                           */
/**********************************************************/
void tsk_ini( void )
{
  reg_tsk( ID_monitor, (void *)stackMonitor, (void *)tsk0_stk, sizeof(tsk0_stk), 0,0,0,0 );
  reg_tsk( ID_switchScan, (void *)switchScanTask, (void *)tsk1_stk, sizeof(tsk1_stk), 0,0,0,0 );
  reg_tsk( ID_pwmGenerate, (void *)pwmGenerateTask, (void *)tsk2_stk, sizeof(tsk2_stk), 0,0,0,0 );

  sta_tsk( ID_monitor );
//  sta_tsk( ID_switchScan );
//  sta_tsk( ID_pwmGenerate );
}

/**********************************************************/
/* stack monitor task                                     */
/**********************************************************/
static unsigned int RemainStack( void *stk, unsigned int sz );
static void stackPrint( const char *msg, void *stk, unsigned int sz );

void stackMonitor( void )
{
  sta_tsk( ID_pwmGenerate );
  while( 1 )
  {
    dly_tsk( 10 * 1000UL );
    stackPrint( "task1 stack : ", tsk1_stk, sizeof(tsk1_stk) );
    stackPrint( "task2 stack : ", tsk2_stk, sizeof(tsk2_stk) );
    stackPrint( "monitor stack : ", tsk0_stk, sizeof(tsk0_stk) );
  }
}

static void stackPrint( const char *msg, void *stk, unsigned int sz )
{
  Serial.print( msg );
  Serial.print( RemainStack( stk, sz ), DEC );
  Serial.print( "/" );
  Serial.println( sz, DEC );
}

static unsigned int RemainStack( void *stk, unsigned int sz )
{
  unsigned int i;
  char *ptr = (char *)stk;

  for( i = 0; i < sz; i++ )
  {
    if( *ptr++ != 0 ) break;
  }

  return sz - i;
//  return i;
}

/**********************************************************/
/* switchScanTask                                         */
/**********************************************************/
void switchScanTask( void )
{
  pinMode( TRIGGER_PIN, INPUT_PULLUP );
  unsigned char sw = 0x00;
  while( 1 )
  {
    sw <<= 1;
    if( digitalRead( TRIGGER_PIN ) == LOW ) sw |= 1;
    if( (sw & 0x0f) == 0x07 )
    {
      switchScanUpdate++;
    }

    dly_tsk( 50UL );
  }
}

/**********************************************************/
/* PWM Generate Task                                      */
/**********************************************************/
void pwmGenerateTask( void )
{
  pinMode( PWM_PIN, OUTPUT );
  digitalWrite( LED_PIN, LOW );
  pinMode( LED_PIN, OUTPUT );

  /* wave table generate. */
  for( int i = 0; i < RESOLUTION; i++ )
  {
    int tempI = (int)(sin( 2 * M_PI * i / RESOLUTION) * scale);
    originalWaveTable[ i ] = tempI;
    waveTable[ i ] = (unsigned int)tempI + offset;
    Serial.print( waveTable[ i ], DEC );
    Serial.print( "," );
    if( (i % 10) == 9 ) Serial.println();
  }

  /* start switch scan task. */
  sta_tsk( ID_switchScan );

  while( 1 )
  {
    /* wait for switch pushed. */
    unsigned char switchScanUpdateBase = switchScanUpdate;
    while( switchScanUpdateBase == switchScanUpdate ) dly_tsk( 50UL );
    switchScanUpdateBase = switchScanUpdate;
    Serial.println( "pwmGenerateTask PWM start." );

    /* timer counter initialize. */
    TCCR1B = 0x00;  //  timer1 stop
    TCNT1 = 0x0000;  // 16bit counter clear
    TIMSK1 = 0x00;  // interrupt disable
    TCCR1A = 0b00100011;  //  0b00 10 00 11
      // OC1A : normal port and not connected OC1A.
      // OC1B : compare match goes OC1B to clear and top goes OC1B to set.
      // fast PWM and top is OCR1A.
    TCCR1B = 0b00011001;  //  0b0 0 0 11 001
      // fast PWM and top is OCR1A.
      // clkIO / 1 priscaller.
    OCR1A = (unsigned int)(TIMER_COUNTER_CLOCK / PWM_FREQUENCY);
    OCR1B = waveTable[ 0 ];
    TIMSK1 = 0x00;

    /* interrupt timer start. */
    slope = 1.0f - DELTA_SLOPE;
    waveTableCounter = 1;
    conversionStart = true;
    digitalWrite( LED_PIN, HIGH );

    /* wait 10s. */
    dly_tsk( 11 * 1000UL );
    conversionStart = false;
    for( int i = 0; i < RESOLUTION; i++ )
    {
      int tempI = originalWaveTable[ i ];
      waveTable[ i ] = (unsigned int)tempI + offset;
    }
    Serial.println( "pwmGenerateTask PWM stop." );
    digitalWrite( LED_PIN, LOW );
  }
}

/**********************************************************/
/* pwm update handler                                     */
/**********************************************************/
void pwmUpdateHandler()
{
  static int count = 0;

  /* system timer update */
  if( count & 1 ) systim += 1UL;
  count++;

  if( conversionStart == true && slope >= 0.0f )
  {
    OCR1B = waveTable[ waveTableCounter ];
    float tempF = (float)originalWaveTable[ waveTableCounter ] * slope;
    waveTable[ waveTableCounter ] = (unsigned int)tempF + offset;
    if( ++waveTableCounter >= RESOLUTION )
    {
      waveTableCounter = 0;
      slope -= DELTA_SLOPE;
    }
  }
}


nice!(0)  コメント(0) 

Arduino AVRでマルチタスクしてみる タスク1 [ATmarquino Arduino]

arduinoAvrMultiTask_001.png

gitHubで公開と言う慣れない事をやっているので、良かったら教えてね!

https://github.com/chobichan/avrMultiTask_001
※ちょっとだけ修正入れています。ダウンロード実績1件、わらった!

サンプルINOは3つのタスクが起動しています。
1.stackMonitor
2.task1
3.task2
ライブラリの非依存部のサービスコールは従来からこのblogで公開している物。
AVRに依存するライブラリを今回新たに作成している。

AVR依存部を作成するにあたって考慮するところ!
※AVR GCCの破壊レジスタ : r0,r18-r27(X register),r30-r31(Z register)

※;AVR GCCの非破壊レジスタ : r2-r17,r28-r29(Y register)

※関数から戻る時は必ずr1レジスタを0にする r1=0

※AVR GCCの最初の引数 : r25:r24、AVR GCCの2番目の引数 : r23:r22、AVR GCCの3番目の引数 : r21:r20、AVR GCCの4番目の引数 : r19:r18

※AVR GCCの戻り値 : r25:r24

コンテキストをスタックに積むところは以下の様にした。
スタックポインタからのオフセットレジスタ
0r29
1r28
2r17
3r16
4r15
5r14
6r13
7r12
8r11
9r10
10r9
11r8
12r7
13r6
14r5
15r4
16r3
17r2
18ステータスレジスタ
19空き
20プログラム・カウンタ 上位
21プログラム・カウンタ 下位


スタックにプログラム・カウンタを積むところで結構嵌った(笑)。

nice!(0)  コメント(0) 

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
前の10件 | - ATmarquino Arduino ブログトップ