2008.12.21

[Arduino]Arduinoでコマンドシーケンサーを作ってみた

ArduinoをPlayStation 2につないで、Arduinoからコマンドの自動入力をさせてみた。

Commandsequencer8

入力するコマンドのシーケンスパターンを記述し、それをArduinoに送信、ArduinoはPlayStation 2の映像出力から取り出した垂直同期に同期して、シーケンスパターンを再生するという寸法。

「最速風神→刻みパンチ→最速風神」。3フレームでコマンド入力している、これがホントの最速風神。シーケンスパターンは、Emacsの矩形編集機能でシコシコ編集。

PlayStationコントローラのプロトコルを実装して、Arduinoを直接PlayStation 2につなぐのがイキというものだろうけど、そんな技術は無い。
コントローラの中に入っているMPUの入力ピンから線を引き出して、外部操作のための端子を付けてみた。

Commandsequencer3

Commandsequencer5

Commandsequencer7_2

そして、前回のChumbyネタ同様、Arduinoでフォトカプラを動作させ、押したいボタンをGNDに落とすというやり方をした。

ブレッドボード上にいろいろと回路を作り込んだので、使ったArduinoはDC Boarduino。これ、なんだかリセット後、動き出すまでが遅いんだよねー。

90%がた動いているのだけど、たまに入力の一部が無視されることがある。
これでは、垂直同期に同期させている甲斐が無い。
どこに原因があるのか調べたいのだけど、こういうときはロジックアナライザやオシロスコープが欲しいねえ。

|

2008.12.07

[Arduino][Chumby]Chumby、Arduino、リモコンをつないで定時に照明を点灯/消灯

ChumbyとArduinoをつないで何かできないかと検討中に目に飛び込んできたのが、照明のリモコン。 これを制御して、決まった時間に照明のON/OFFをしてみたい。目覚ましと同時に照明が点灯、などという使い方が想定できる。

Chumbyarduino11

まずは照明のリモコンを、Arduinoで制御できるよう改造。 リモコンのスイッチにフォトカプラを仕込み、Arduino接続用の端子を設ける。

免責

ここに書いたことを実行したことによる結果の責任を負いません。

試す場合は自己責任にてお願いします。

リモコンの改造

Chumbyarduino9

▲リモコンはNOATEK NE-747N。以前東急ハンズで買ったもの。既に生産中止のようだ。現行品としてはNE-657Nというものがあるそう。別に今回の用途を想定したわけではないけれども、電波式ということで選んだもの。

Chumbyarduino2

▲タクトスイッチの四つある端子のうち、二つは同じもの。普段は端子間の幅の狭い方が不導通状態になっており、スイッチを押すと導通状態になる。テスターで調べるとすぐ分かる。常に導通状態にある幅の広い端子間にフォトカプラを仕込んでも意味が無いので注意。

Chumbyarduino3_2

▲基板上にあるタクトスイッチの端子間に、フォトカプラのトランジスタ側をつなぐ。フォトカプラのエミッタ側がスイッチのGND側になるようにする。

Chumbyarduinoschimatic

▲全体の接続図。フォトカプラはPC817Cを使用。

Chumbyarduino1

▲フォトカプラのアノード側に抵抗を入れる。220Ω。できるだけ電流は少なくした方が寿命が長くなるそうなので、動作する最大の抵抗を入れるといいかも。

Chumbyarduino5_2

▲組み付け。ショートしないよう、熱収縮チューブでカバーした。

Chumbyarduino6

▲スイッチの端子配列が線対称になっているので、二つあるフォトカプラは表裏向きを逆に取り付けている。

Chumbyarduino4

▲ケースにソケット用の穴を開ける。ドリルで穴を開けて、ニッパでつなぐという定番の工法を取った。

Chumbyarduino7

▲ソケットはホットボンドで固定。ちなみに、このソケット、eZ430-F2013用に鈴商で買った1.27mmピッチのもの。

Chumbyarduino8

Arduino側の準備

Arduinoには以下のファームウェアを転送しておく。9600bpsでシリアル通信を開始。「a」が来たら2番ピンを500ms HIGHにし、「b」が来たら3番ピンを500ms HIGHにする、という単純なもの。 今回は2番ピンにリモコンのONスイッチにつないだフォトカプラを、3番ピンにOFFスイッチにつないだフォトカプラをつないでいるので、これであたかもリモコンのボタンを押したかのように制御できる。

byte res;
#define ledPin 13
#define onPin 2
#define offPin 3

void setup()
{
  Serial.begin(9600);
  pinMode(onPin, OUTPUT);
  pinMode(offPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(onPin, LOW);
  digitalWrite(offPin, LOW);
  digitalWrite(ledPin, LOW);
}

void loop()
{
  if(Serial.available())
    while(Serial.available() > 0)
    {
      res = Serial.read();
      if (res == 'a')
      {
        digitalWrite(onPin, HIGH);
        digitalWrite(ledPin, HIGH);
        delay(500);
        digitalWrite(onPin, LOW);
        digitalWrite(ledPin, LOW);
      }
      if (res == 'b')
      {
        digitalWrite(offPin, HIGH);
        digitalWrite(ledPin, HIGH);
        delay(500);
        digitalWrite(offPin, LOW);
        digitalWrite(ledPin, LOW);
      }
    }
}

Chumby側の準備

ChumbyとArduinoの間で通信をするには、カーネルモジュールをインストールする必要がある。 Chumbyの最近のファームウェアには、最初からArduinoで使えるカーネルモジュールが入っているので、スクリプトを書けばOK。

以下のスクリプトを、ArduinoをChumbyのUSB端子につないでから実行するか、Arduinoを接続し、USBメモリのルートディレクトリにファイル名「debugchumby」としてコピーしておいて、そのUSBメモリを挿入したまま一度Chumbyを立ち上げ直せばArduinoが使えるようになるはず。

#!/bin/sh

regmod () {
    lsmod | grep "${1}" >/dev/null   
    if [ $? -eq 1 ]; then               
        insmod /drivers/${1}.ko
    fi
}

regmod usbserial
regmod ftdi_sio

sleep 5

if [ -e "/dev/ttyUSB0" ]; then
    ps | grep gett[y] >/dev/null
    if [ $? -eq 1 ]; then
        /sbin/getty 9600 /dev/ttyUSB0 &
    fi
fi

ChumbyにSSHでログインし、以下のコマンドを実行するとArduinoにつないだリモコンを操作できる。

# echo 'a'> /dev/ttyUSB0
# echo 'b'> /dev/ttyUSB0

ちなみに、今回は使っていないが、Arduino側からシリアル通信で送られた文字を参照したくば、以下のようにする。

# dd if=/dev/ttyUSB0 bs=1 count=5 2>/dev/null

(5バイト受信して標準出力へ)

スケジュールを組んで制御するには、Chumbyで最初から動作しているcronを使う。 Custom Alarmでスクリプトを実行できたような気がするのだけど、情報が出てこない。 cronにスケジュールを登録するには、ChumbyにSSHでログインして以下のコマンドを実行。

# crontab -e

viが起動して編集状態になるので、以下のようなエントリを追加すると、今回の例では毎朝8:30に照明が点灯することになる。

30 8 * * * echo 'a'> /dev/ttyUSB0

viの操作は次の通り。「Goecho 'a'> /dev/ttyUSB0[Esc]:wq」cronについての詳しくはGoogleなどで調べてください。

次のようにすれば、15分後に消灯する。

30 8 * * * echo 'a'> /dev/ttyUSB0
45 8 * * * echo 'b'> /dev/ttyUSB0

Chumbyに接続したArduinoをネットワーク経由でコントロール

Fenrir's BLogさんの「ChumbyでArduino等をFlashからコントロールする方法 (XMLSocketが使える?)」で公開されているserproxyのパッチを適用したものをChumby用にビルドしたので置いときます。

「chumbyserproxy-0.1.3.tar.gz」をダウンロード

これを実行しておくと、Chumbyのシリアルポートをネットワークに転送できる。 つまり、ChumbyにつないだArduinoをネットワークから制御できるようになる。

Chumby側の操作

# cp serproxy serproxy.cfg /psp
# cd /psp
# ./serproxy &

母艦側の操作

$ telnet [chumbyのIP] 5331
a
b

デフォルトでは19200bpsでポートを初期化しているので、Arduino側では「Serial.begin(19200); 」するファームウェアを焼いておくか、serproxyの設定をArduino側のbpsに合わせる必要がある。

これを使わなくともSSH経由で操作できるが、Chumbyのsshdは不安定なので、こちらの方がいいかも。

|

2008.11.30

[AVR]ハローキティのAVRライター新発売!!

ハローキティのAVRライター新発売!!

Hellokittyavrwriter1

Hellokittyavrwriter2_2

Hellokittyavrwriter3_2

|

2008.11.17

[AVR][Gainer]小型Gainer互換機pepperを作って遊んでみた

AVR ATtiny45/85を使ったGainer互換機、pepperを作って遊んでみた。

morecat lab.さんでは、このほかATmega88Pを使ったginger、ATmega644Pを使ったsugarなどのGainer互換機を作られているが、その小ささに惚れ、Pepper-MIDIというインターフェースを接続すると学研の付録シンセ、SX-150をMIDI化できるということもあって、pepperを選択した。

とりあえず部品のレイアウトは公式のプリント基板と同じにして、ジャンパを飛ばしまくってつじつまを合わせてみた。

Pepper1

▲所定のサイズの基板で作らないと価値半減なので、ユニバーサル基板からの切り出しをがんばった。

Pepper2

▲手のひらでコロコロともてあそべるサイズ。

Pepper3

▲USBに直結可能。通常この手のものに必要な、12MHzのクリスタルさえ省略した作りになっている。

Pepper4

▲CdSを接続してみた。pepperが小さいので、USBケーブルの先に、センサなどを直結できる感覚。

Pepper5

▲学研の付録シンセ、SX-150を接続するインターフェース、Pepper-MIDI。

Pepper6_2

▲Pepper-MIDIを介してSX-150を接続。

Processingからのアクセス(Mac OS X)

pepperはGainerとして機能するので、pepperをProcessingで使うには、Gainer用のライブラリをProcessingにインストールすればいい。 Gainerの公式ページには、Mac OS Xでは「/Applications/Processing/libraries/serial/macosx_setup.command」を実行しろ、という説明があるが、これは古い手順で、そのようなファイルは無い。

現在は、「/Applications/Processing/Contents/Resources/Java/Libraries/serial/library/RXTXcomm.jar」を、「/Applications/Processing/Contents/Resources/Java/Libraries/gainer/library/RXTXcomm.jar」へコピー、というのが正しい手順となる。

pepperのピン配列は以下の通り。

+5V ai0 ao1 ao0 ai1 GND

アナログ入力二つがアナログ出力二つを囲むような形になっている。 また、Processingからpepperの各ポートへのアクセスは、以下のようなコードでできる。

//出力
//2番目の引数は0〜255の整数
//ao0
gainer.analogOutput(0, 0);
//ao1
gainer.analogOutput(1, 255);

//入力
int res0, res1;
gainer.peekAnalogInput();
//ai0
res0 = gainer.analogInput[0];
//ai1
res1 = gainer.analogInput[1];

※「gainer.peekAnalogInput()」を実行しないと、値が取得できないので注意。

デフォルトのCONFIGURATION_1にはデジタルI/Oが無いので、四つあるポートはすべてアナログ系の関数でアクセスする。

|

2008.11.12

[AVR]AVRライターHIDaspxを作ってみた

AVR業界ではおなじみsenshuさんがメンテナンスされている、AVRライターのHIDaspxが素晴らしい感じなので、作ってみることにした。

Hidaspx1_2

特徴は、

  • ドライバが要らない(HID = Human Interface Deviceとして認識する)
  • ATtiny2313(秋月で100円)一つでできる
  • 直接USB接続ができる
  • FT232RなどのUSB-Serialコンバータが要らない
  • Mac OS Xでも使える
  • GIPOモードが付いている(USB-IO的な、あるいはFT232RのBit Bangモード的な)

Hidaspx2

こちらのkumanさんの2台目の回路図を手本に、力弱くユニバーサル基板で。
部品のレイアウトはアドホックな感じで進めていったんだけど、案外うまく収まった。
考えなしに縦置きにしたけど、これはどう考えても横置きした方が楽だったような。

Hidaspx3

まずはVMware Fusion上のWindows XPから使ってみた。
速い! しかも、AT90S2313、AT90S1200などのレガシーデバイスでも問題無く読み書きできる。

Mac OS Xでは、HIDaspxの源流となったHIDaspを作られた、瓶詰堂さんが配布されている「hidspx for MacOS X」を使ってみたところ、何だか遅いみたい? でも使えてはいる。
これがWindows上での速さぐらいになってくれると助かるなあ。

Hidaspx4

↑左のやつは以前作ったMorosanさんの、PICを使ったAVRライター。こちらはRS-232Cだけれども、STK500互換として機能し、AVR Studioから書き込める素晴らしいもの。PICライターしか持っていなかった時代に、これを使って初めてAVRに書き込んだときの感動ったら無かった。

|

2008.11.04

[iPhone][AVR][Jailbreak]自走式iPhoneを作ってみた

iPhoneのシリアルポートを使った工作が面白いので、今度は「自走式iPhone」を作ってみた。

Selfpropellediphone01

ハードウェア

ベースは、TAMIYAの楽しい工作シリーズNo.68「壁づたいねずみ工作基本セット」。 CPUボード&開発環境にArduino(ボードはArduino Diecimila)を利用。

Selfpropellediphone02

ArduinoのProtoShield上にモータードライバのTA7291P (PDF)を二つ設置、これでモーターを制御。 TA7291P×2の入力ピン計4本に、ArduinoのPWM出力ができるピン、5, 6, 9, 10を接続。 自走式iPhoneの重量に耐えるため、AA×4本を直列につないだ電源でモーターを駆動。

Selfpropellediphone03

そのほか、Arduinoの電源となる009P電池、そこから安定化した5Vを作るレギュレータ回路なども載ってぶら下がっている。

Selfpropellediphone04

Selfpropellediphone05

ソフトウェア

Arduinoのソフトウェアは、シリアル通信を監視して、コマンド文字が来たらそれに応答、という簡単なもの。 コマンド文字に応じて、TA7291Pの所定のピンをHレベルにする。 PWM制御できるポートを使っているので、一応0〜255までの256段階でモーターのスピードを調整できるが、トルクが無いのでなかなか調整が難しい。

#define FORWARD 1
#define BACKWARD 2
#define STOP 3
#define RIGHT 4
#define LEFT 5

int rightForward = 10;
int rightBackward = 9;
int leftForward = 6;
int leftBackward = 5;

int incomingByte = 0;
int spd = 100;
int currentVector = STOP;

void setup() {
  pinMode(rightForward, OUTPUT);
  pinMode(rightBackward, OUTPUT);
  pinMode(leftForward, OUTPUT);
  pinMode(leftBackward, OUTPUT);

  Serial.begin(9600);
  Serial.println("start");
}

void loop() {
  if(Serial.available() > 0)
  {
    incomingByte = Serial.read();
    Serial.println(incomingByte);
    switch (incomingByte) {
      case 120:
        goBackward(spd);
        break;
      case 119:
        if (spd > 0)
        {
          spd -= 10;
        }
        updateSpeed();
        //Serial.println(spd);
        break;
      case 115:
        turnLeft(spd);
        break;
      case 113:
        if (spd <= 250)
        {
          spd += 10;
        }
        updateSpeed();
        //Serial.println(spd);
        break;
      case 101:
        goForward(spd);
        break;
      case 100:
        turnRight(spd);
        break;
      case 97:
        stop();
        break;
    }
  }
}

void updateSpeed()
{
  switch (currentVector)
  {
    case LEFT:
      turnLeft(spd);
      break;
    case RIGHT:
      turnRight(spd);
      break;
    case STOP:
      stop();
      break;
    case BACKWARD:
      goBackward(spd);
      break;
    case FORWARD:
      goForward(spd);
      break;
  }
}

void goForward(int spd)
{
  stop();
  analogWrite(leftForward, spd);
  analogWrite(rightForward, spd);
  currentVector = FORWARD;
}

void goBackward(int spd)
{
  stop();
  analogWrite(leftBackward, spd);
  analogWrite(rightBackward, spd);
  currentVector = BACKWARD;
}

void turnRight(int spd)
{
  stop();
  analogWrite(leftBackward, spd);
  analogWrite(rightForward, spd);
  currentVector = RIGHT;
}

void turnLeft(int spd)
{
  stop();
  analogWrite(leftForward, spd);
  analogWrite(rightBackward, spd);
  currentVector = LEFT;
}

void stop()
{
  analogWrite(rightForward, 0);
  analogWrite(rightBackward, 0);
  analogWrite(leftForward, 0);
  analogWrite(leftBackward, 0);
  currentVector = STOP;
}

iPhone上で動かすソフトウェアは、適当なポートでListenし、送られてきた文字をシリアルポートにフォワードするというもの。 この働きで、iPhoneが無線モジュールとして機能することになる。これはRubyで書いた。

#!/usr/bin/env ruby

require "socket"
require "serialport"

class Arduino

  def initialize(serialport = "/dev/tty.iap", serverport = 12345)

    if (not File.exist?(serialport))
      raise "ERROR: Specified device does not exist."
    end
    @sp = SerialPort.new(serialport, 9600, 8, 1, SerialPort::NONE)

    @gs = TCPServer.open(serverport)
    while true
      @socks = [@gs]
      @addr = @gs.addr
      @addr.shift
      printf("server is on %s\n", @addr.join(":"))
      run()
    end
  end
  def run()
    while true
      nsock = select(@socks)
      next if nsock == nil
      for s in nsock[0]
        if s == @gs
          @socks.push(s.accept)
          print(s, " is accepted\n")
        else
          if s.eof?
            print(s, " is gone\n")
            s.close
            @socks.delete(s)
          else
            str = s.gets
            if str.chomp == "end"
              s.close
              return
            end
            @sp.puts(str)
          end
        end
      end
    end
  end
end

arduino = Arduino.new("/dev/tty.iap", 12345)

クライアントは特に書いてないので、telnetから操作した。

$ telnet 192.168.0.5 12345

なかなか面白い遊びであった。

|

2008.10.27

[iPhone][AVR]iPhone/iPod touch用Dock Connector型温度センサを作ってみた

AVRマイコンATtiny45と温度センサLM60をDock Connectorの中に内蔵して、「Dock Connector型温度センサ」を完成させてみた。

Iphone_thermometer05

iPhoneにこのDock Connector型温度センサを接続すると、中に入っているマイコン、ATtiny45が温度センサLM60から温度を読み取って摂氏に変換し、iPhoneへシリアルポート経由で送信を始める。

iPhone側でシリアルポートを読んでみると……、

$ cat /dev/tty.iap
0.590968783
26.7
0.590968783
26.7
0.590968783
26.7
0.597414015
27.7
0.597414015
27.7
.........

こんな感じ。やたら桁の多いのは、ADCで読み取ったLM60の電圧そのもの。
ただ、精度の高くない浮動小数点演算の結果なので、下位の方は意味が無い。

UIを作って、温度計然とした体裁にすることももちろんできるけど、作るかどうか分からない。

ログをgnuplotでグラフにしてみた。

Templog

会社から外に出た直後にログ取り開始。駅までの道のりで、温度が急激に低下。電車に乗ると上がり、駅から家までの道のりでまた低下、自宅は25度ぐらいで安定、といった感じできれいに取れている。

「Dock Connector型温度センサ」の中身

Iphone_thermometer01
↑LM60をATtiny45の上に乗せてみた。裸の銅線みたいなのはUEW線。裸なようでウレタンの皮膜がある。

Iphone_thermometer02
↑ATtiny45の裏側には、一応パスコンを付けてみた。

Iphone_thermometer03
↑こんな感じに組み込まれる。右側の金属フレームを破壊してスペースを作っている。

Iphone_thermometer04
↑シールで巻いて絶縁。

Iphone_thermometer06
↑部品たちといっしょに撮影。

関連エントリ

[iPhone][AVR]続・iPhoneにAVRマイコン(Atmel ATtiny45)をつなぎ温度計測してみた

[iPhone][AVR]iPhoneにAVRマイコン(Atmel ATtiny45)をつなぎ温度計測してみた

[iPhone][AVR]iPhoneにAVRマイコン(Atmel ATtiny2313)をつないでみた

|

2008.10.26

[iPhone][AVR]続・iPhoneにAVRマイコン(Atmel ATtiny45)をつなぎ温度計測してみた

[iPhone][AVR]iPhoneにAVRマイコン(Atmel ATtiny45)をつなぎ温度計測してみたの続き。

AVR ATtiny45内蔵温度センサを使ってみたものの、どうにもわけ分からん結果しか出なかったので、温度センサLM60を外付けして再チャレンジ。

Iphoneavr06

例のアテにならない内蔵基準電圧については、動作環境での読み取り電圧をLM60からの出力をテスタで計測した電圧と大体合わせてやるという方法で適当に校正してやれば、それなりに動作しているようだ。SOTパッケージのLM60を買ってこよう。

Iphoneavr07_2

ソースは、内蔵ADC1を使い、LM60からの入力を読み取り、摂氏温度に変換するという処理内容。

BASCOM-AVRにはprintfの"%01.2f"みたいなものが無いみたいなので、文字列処理で小数点第1位まで表示。

'-----------------------------
'Compiler Options
'-----------------------------

$regfile = "attiny45.dat"
$crystal = 1000000

$hwstack = 24
$swstack = 16
$framesize = 32

'-----------------------------
'Variable Definitions
'-----------------------------

Dim I As Byte
Dim Sum As Word
Dim Intpart As Integer
Dim Fracpart As Single
Dim Fracpartstr As String * 11
Dim Res As Single

'-----------------------------
'Constant Definitions
'-----------------------------

'ADC1(Pin:7)
Const Channel = 1
'Reference Voltage
Const Refvcc = 1.1

'-----------------------------
'Peripheral Settings
'-----------------------------

'PB1(Pin:6): Serial TX
Open "COMB.1:9600,8,N,1" For Output As #1

'PB3(Pin:2): LED
Config Portb.3 = Output

Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1
'Config Adc = Single , Prescaler = Auto , Reference = Avcc

'ADC Ref 1.1V / Use Temperature Sensor
'Admux = &B10001111

'ADC Ref VCC / Use ADC1
'Admux = &B00000001

Start Adc

'-----------------------------
'Main Loop
'-----------------------------

Do
   Sum = 0

   For I = 1 To 100
      Sum = Sum + Getadc(channel)
   Next I

   Rem (format "%01.2f" (* (/ (- (/ (* 123 4.98) 1024.0) 0.424) 6.25) 1000.0))

   'Average Up
   Sum = Sum / 100
   'Dependent on Reference Voltage
   Res = Sum * Refvcc
   Res = Res / 1024.0
   'Internal_1.1 Offset
   'Res = Res - 0.015
   Res = Res - 0.005
   'Debug Print
   'Print #1 , Res
   'DC Offset 424mV
   Res = Res - 0.424
   '6.25mV/C
   Res = Res / 6.25
   Res = Res * 1000.0

   'Formatting
   Intpart = Int(res)
   Fracpart = Frac(res)
   Fracpartstr = Str(fracpart)
   Fracpartstr = Mid(fracpartstr , 2 , 2)

   Print #1 , Intpart ; Fracpartstr

   'LED Flash
   Gosub Ledflash
Loop

Close #1

End

'-----------------------------
'Subroutine Definitions
'-----------------------------

Ledflash:
   Set Portb.3
   Waitms 200
   Reset Portb.3
   Waitms 500
   Return

|

[AVR]ATmega644P版ArduinoであるところのSanguinoのキットが到着したので作ってみた

Sanguino01

注文していたSanguinoのキットが到着したので、早速作ってみた。せっかくなのでATmega644Pは自分で焼いたものを使用。

Sanguino02

Sanguinoとは、ATmega644Pを搭載したBoarduinoのこと。
ブレッドボード遊びに適した形状をしている。
ArduinoのIDEを流用する、Arduinoの上位コンパチみたいなもの。
Arduinoに付いているLEDは13番だが、Sanguinoの場合は0番である点などが地味に違ったりする。

ATmega644Pなので、64KBのフラッシュ、32本のI/O、2チャンネルあるUSARTなどが魅力。

Sanguino03_2

キットに入っている角ピンのピンヘッダーをそのまま使うとブレッドボードから抜けなくなるので、秋月で買った丸ピンICソケット・両端オスピンを使って組み立てた。
これはDC Boarduinoを作ったときの教訓。DC Boarduinoですらなかなか抜けなかったのに、Sanguinoの場合はどうなることやら。

注意すべきは、大きいので、ブレッドボードの電源列をまたぐように挿さないとダメだということ。
普通の挿し方をすると左右合計で1列だけ余るので、どっちかの列のみにしかつなげない状態になってしまう。

Sanguinoには、6ピン1列のUSART端子のほか、6ピン2列のICSP端子、JTAG端子が付いている。

Sanguino04_2

一つだと送料の方が高くなってしまうので、基板のみやら予備をいくつか買ってみた。

Sanguino05

|

2008.10.25

[iPhone][AVR]iPhoneにAVRマイコン(Atmel ATtiny45)をつなぎ温度計測してみた

ATtiny2313にはADCが無いから、LM35DZLM60のようなアナログセンサーがつなげないじゃん、ということで、ADCはもとより、温度センサーまで内蔵かつ8ピンDIPで小さいATtiny45を使ってみた。

Iphoneavr04

↑写真は、Dock Connectorの中にどう納めようかと置いてみただけ。

ちなみに、SOIC版のATtiny2313であるATtiny2313-20SUは、国内ではマルツでしか手に入らないみたいだけど、店頭には置いておらず通販専用商品とのことなのでご注意あれ。

ATtiny45はATtiny45で、ADCや、温度センサーはあっても、USARTが無くてiPhoneとシリアル通信ができないじゃん、と思いきや、ソフトウェアで実装する方法があるとのこと。

ICのblog: Tiny26Lでシリアル通信

オプティマイズ: 最新AVRチップ(ATtiny45等のソフトウェアUARTサンプルコード)

また、BASCOM-AVRにも任意のUSART/UARTポート以外のGPIOをシリアルポートとして機能させることができる、ソフトウェアUART機能があるということを知った。以下のソースを見ての通りすげー簡単だ。

というわけで、ソフトウェアUARTが簡単に書けるBASCOM-AVRで書いてみた。

動作は、ATtiny45内蔵の温度センサーから値を取得し、それをソフトウェアUARTポートとして設定したPB1から「9600bps/8/1/NONE」で繰り返し送信するというもの。

BASCOM-AVRのForumにあったスレッド「ATTiny44 ADC reference selection」を参考にさせてもらった。

$regfile = "attiny45.dat"
$crystal = 8000000

$hwstack = 24
$swstack = 16
$framesize = 32

Dim Lsb_adc As Byte                                         'ADC least significant byte
Dim Msb_adc As Byte                                         'ADC most significant byte
Dim Adc_value As Word At Lsb_adc Overlay
Dim I As Byte
Dim Summary As Integer
Dim Offset As Word

Offset = 281

Config Portb.3 = Output                                     'LED

Open "COMB.1:9600,8,N,1" For Output As #1                   'PB1 used for serial output
Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1

'ADC Ref 1.1V / Use Temperature Sensor
Admux = &B10001111

Start Adc

Do
   Summary = 0

   For I = 1 To 100

      Set Adcsra.adsc                                       'Start conversion

      While Adcsra.adsc = 1
         'Wait conversion to complete
      Wend

      Lsb_adc = Adcl                                        'Get least significant byte
      Msb_adc = Adch

      Summary = Summary + Adc_value

   Next I

   Summary = Summary / 100                                  'Average
   Summary = Summary - Offset

   Print #1 , Summary

   Set Portb.3                                              'LED Flash
   Waitms 200
   Reset Portb.3
   Waitms 500
Loop

End

Iphoneavr05

しかし、取れる値がどうも変だ。ADCから来る最下位が1度に相当するとのことでおおざっぱだし。

すzのAVR研究: 内部温度計のキャリブレーション

こちらのページでの検証によると、ATtiny45等の内蔵温度センサーならびに内蔵基準電圧はアテにならないそうだ。確かに変だ。5Vで動作させているときと、iPhoneの3.3Vで動作させているときで値が全然違うし。8MHz動作と1MHz動作でも全然違う。何だかよく分からない。

よく分かってないので、プログラムや自分の操作が変かもしれない(どこか変だったら教えてください)。

しかし、まがりなりにもATtiny45をiPhoneのDock Connectorからの電源供給で動作させ、内蔵の温度センサーから温度を取得して、iPhoneに送信、iPhoneで受信して表示というところまではできた。勉強になった。

精度的に使いものにならないので、基準電圧を外部から供給し、温度センサーを外部につないでどうなるか、それがDock Connectorに内蔵できそうかという模索に逆戻りだね。

|