2012/02/18

秋月の電波時計用バーアンテナ

,
 秋月の40kHzバーアンテナって、60kHz用バーアンテナに付いている0.012uFコンデンサを、0.027uFにかえたものらしいですね。

というのも、電波時計キットの交換用なのでしょうけど、秋月って60kHz用バーアンテナは単品で売ってるんです。それで、なんか訂正で40kHzと60kHz用の違いが写真で出てたんですよね。どうやら、間違えて入れちゃったらしい。

しかし、電波時計を自作する人って、あまりいないですよね。なんでだろう。
(2014/05/01 加筆修正)
Read more →

2012/02/12

1AD4 A級推薦値

,
1AD4なるサブミニチュア管があります。2本。秋葉ので半月ほど前に買って来ました。
MT管ST管ナス管とかもいいですが、なんつーかかわええのです。

データシートがNXP(Philips)以外見つからなく、昔どっかで見たA級増幅の推薦値みたいなものが無くなったら困るのでメモしときます。

Class A Amplifier
Plate Voltage ................................. 45 V
Grid No. 2 Voltage ............................ 45 V
Grid No. 1 Voltage ............................ 0 V
Plate Resistance (approx) ..................... 500K Ω
Transconductance .............................. 2000 μ
Plate Current ................................. 3 mA
Grid No. 2 Current ............................ 0.8 mA
(出典:NJ7P Tube Database Search)

ところで45Vなんて中途半端な電圧、どうやって用意しよう…
Read more →

2012/02/10

[電子工作]aitendoのDDSモジュールを動かす

,
aitendoで売っている、AD9850がのったモジュールを使ってみました。
このモジュールには、Analog DevicesのAD9850(datasheet)というDDS ICが乗っていますが、海外のサイトにこのICのArduino向けライブラリがあったので、それを使って動作確認してみました。

 AD9850のライブラリはこのページの一番下、「AD9850 Arduino Library.」からZipでDLできます。これを解凍し、Arduinoのlibrariesフォルダの中に入れる(arduino-0021/libraries/EF_AD9850のような感じ)と、Arduino IDEの[Sketch]→[Import Library]で選択できるようになり、使えるようになります。

 ※2012-12-23追記 : ArduinoIDEの更新に伴い、"WProgram.h"が"Arduino.h"になりました。そのため、ライブラリがそのままではコンパイル通らないことがあります。その時は、EF_AD9850/EF_AD9850.hの"WProgram.h"を"Arduino.h"にしてみてください。

ハードウェア

ライブラリの使い方、モジュールとArduino間の結線も、上で紹介したページに書かれています。DDSモジュールのピン配置は、このページにあります。一応書いておくと、
DDS module - Arduino Duemilanoveで
GND - GND
Vcc - Vcc(3.3V)
D7 - Digital 8
CLK - Digital 9
FQUP - Digital 10
REST - Digital 11
です。一応Vcc=3.3Vなので、Arduino側のI/O電圧も3.3Vにしました。5Vな方は自分で調べてください。

ジャンパの設定は、J1、J3がジャンパ。J2は無くても大丈夫っぽいです。

ソフトウェア

プログラムは簡単で、
#include < EF_AD9850.h >

EF_AD9850 AD9850(9,10,11,8);

void setup()
{
  AD9850.init();
  AD9850.reset();
  AD9850.wr_serial(0x00, 1000);
}

void loop()
{
}
です。これも上のページのサンプルコードこのまんまですね。
 これを実行したところ、DDSモジュールのOUT-GND間からsin波が出力されました。クリスタルイヤホンを直繋ぎでも確認できます。

 AD9850は"それなりに"高性能なDDSで、最大60MHzまでのsin波を出力することができます。わざわざ発振器を買わなくても、手軽な信号源とすることができるので便利ですね。簡易network analyzer(作例pdf)を作る試みをしてる人もいるみたいです。
#まだデータシート見てないのに動かせるなんて…
(2014/05/01 加筆修正)
Read more →

2011/12/04

擬似乱数、rand()もどき

,
Cで乱数を発生させる場合、特に精度を求めなければ、普通はrand() (<stdlib.h>)を使うことになります。が、もっと簡単なのでいい、という場合もあります。探してたら見つかったのでメモです。

これ:PICを使い乱数を発生させてLEDをランダムに光らせたいのですがプログラムがよくわ... - Yahoo!知恵袋

ちなみに、Attiny13Aでstdlib.hのrand()だと780byte程だったのが、上で紹介されてたrand()にしたら400byte弱になりましたとさ。ただまあ、まだ試してはいない←
Read more →

[電子工作]AVRの逆アセンブラ、avr-objdump.exeを使う

,
 AVRの逆アセンブラ、avr-objdumpの話です。

 WinAVRでプログラムを書いていて、「どうしてこんなメモリを喰うんだろう?」と思う時がありました。Cのコードを少し変えただけなのに、です。こんな時は、コンパイル結果である機械語のコードが全く違っていたりするので、確認のためにアセンブリのソースも見ないといけません。となると、逆アセンブラの出番になります。

 …前置きが長いですが、AVRの逆アセンブラ、「avr-objdump.exe」についてのメモです。
 この実行ファイルのオプションを知るには、avr-objdump.exeのmanを見て頂くのが早いです。一応、コマンドラインでただavr-objdumpと入力しても、オプション一覧が出ると思います。下にオプション一覧の画面を貼ってきます。

avr-objdump.exeのオプション一覧

 逆アセンブラを吐き出すためには、一旦C/C++で作成したプロジェクトをMake Allし、できたファイルのうちのオブジェクトファイル(拡張子は.o、大抵main.oとか)が必要です。コマンドラインで、avr-objdump -S main.o とすれば、逆アセンブラのリストがずらーっと並びます。テキストファイルなどにしたい場合は、avr-objdump -S main.o > dump.txtなどとすれば、そのディレクトリの中にdump.txtが作成され、以下のように逆アセンブラが出力されます。

逆アセンブラした結果(サクラエディタで閲覧)

 ちなみに私の場合、_delay_ms()がメモリを消費していたみたいです。直接の原因かは分かりませんが、公式には「The maximal possible delay is 262.14 ms / F_CPU in MHz.」と書かれているので、あまり大きな引数(400とか)にするのは考えものですね… 
Read more →

2011/10/21

[電子工作]TEA5767搭載FMモジュールを、Arduinoから動かす

,
 Arduinoから、aitendoから発売されているTEA5767モジュールを動かしてみました。
 TEA5767はFMレシーバICで、I2C or SPI機能を持つので、スレーブとしてマイコンに接続することができます。しかし、aitendoのモジュールは、最初からI2C専用の設計になっています(PinがSDAとSCLしかない)。なので、今回は、ArduinoからI2C経由で制御します。

 ところでこのモジュール、アンテナ端子がイヤホンのGNDと100Ωで繋がってる気がするんですが、これってどうなんでしょう?ELMさんのMP3プレーヤーの作例では、イヤホンアンテナとするためなのか、RDA5800のアンテナ端子とイヤホンのGNDを1pでつないでるみたいですが。アナログ高周波回路、よくわかりません…

配線

I2Cのバス2本、Vcc、GNDをArduinoに接続します。Arduino Duemilanoveの場合、
SDAはAnalog 4
SCLはAnalog 5
です。

コード

以下にコードを置いておきます。参考程度にどうぞ。
 内容は、指定した周波数を受信するようにさせるだけのシンプルなものです。各パラメータは、データシートのp11-p17あたりが詳しいです。
 設定するPLLの値は、このサイトさんに、周波数との対応表があるので参考にさせて頂きました。

#include <Wire.h>

//82.5 NHK-FM 2772
//81.3 J-WAVE 26DF
//write addr
const int addr = 0b1100000;
const char data1 = 0x27;
const char data2 = 0x72;
const char data3 = 0x10;
const char data4 = 0x36;
const char data5 = 0b00000000;

void setup()
{
  delay(1000);
  
  Serial.begin(9600);
  Wire.begin();
  //Serial.print(Wire.requestFrom(addr, 5));
  Wire.beginTransmission(addr);
  //Wire.send(0b11000000);
  Wire.send(data1);
  Wire.send(data2);
  Wire.send(data3);
  Wire.send(data4);
  Wire.send(data5);
  Wire.endTransmission();
  Serial.print("end");
}

void loop()
{
}

悩んだこと

Wire.beginTransmission(addr);
のaddrは0~127までの値です。I2Cのアドレスは大抵Lower bit(LSB?)が0か1かでRead/Writeの判断をすると思うのですが、この場合その最下位1bitを切り捨て、残り7bitを右シフトさせ0~127の範囲に収めてaddrに指定するみたいです。詳細は公式リファレンスをどうぞ。

「Wire.beginTransmission(addr);はアドレスをI2Cバスに送るか?」
実はここでかなり悩み、時間をとられました。何しろアマチュアなので原因の切り分けがなかなかできません。
日本語リファレンスには、「指定したアドレスのI2Cスレーブに対して送信処理を始めます。」とあります。
実際、TEA5767はI2Cの場合、addr, data[0], data[1], data[2], data[3], data[4]の6byteをたてつづけに送る必要があるみたいですが、Wire.send()を用いてaddrからもう一度送ると、上手く動きません。どうやら、Wire.beginTransmission()では特定のスレーブを受信体制にするために、I2Cバスにaddrを送信すると思うのですが、どうなんでしょう…。
Read more →

2011/09/01

C#でマンデルブロ集合を描いてみた

,






















練習がてら書いてみました。だいたい3時間。
マンデルブロ集合たん綺麗だよ'`ァ,、ァ(*´Д`*)'`ァ,、ァ
マンデルブロ集合は複素数を扱うので、複素数クラスを探したのですが、公式だと.Net Framework4からしかComplexクラスが入ってないので、しょうがないので自分で書きました。ぐぐっても複素数クラスをジェネリック?を使ったりして「如何に上手く作るか」説明してあるサイトはあったのですが、初心者向けの簡単なクラスは見つかりませんでした…(´・ω・`)
正直こういうところは動作が確実な、そして俺でも読める(重要)ライブラリを拝借するのが一番楽で確実と思うですよ?

コードの解説。

1) 色
Wikiには、マンデルブロ集合の周りも発散の速度で色分けしてあります。よって、発散まで(Infinityがtrue)のループ回数で判定してますが、結構シビアです。大抵は殆ど直ぐに発散します。集合の境界あたりは発散までの回数が急激に変わるみたいです。

2) delegate
マルチスレッドじゃないと重くてやってらんねーので、UIを弄るときはマルチスレッド特有の処理が必要です。ここらへん素人なので他のサイトをあたってくだしあ

3) ループ回数
今のところ10000回です。どっかのサイトに10000回って書いてあるのを昔見た気がする、それが全て。

4) 複素数クラス
長くなったので別の投稿にするかもですね。
Complexとある所は全て自分の複素数クラスです。

5) UI
WindowSize : width 480, height 480
Button1 : これを押すとDrawします。
Label1 : ループが何回目かを表示します。
えっと、参考にしてください。

ええと、C#について幾つか今日はじめて知ったことを。
(´ー`)oO(この言語進化するの早すぎだろ…)

1) checked, unchecked
これを書くとOverflowがごにょごにょ こちらのリンク先に詳しい説明がありました。

2) doubleはOverflow Exceptionを投げない
これも上のリンク先に(ry

3) Double.IsPositiveInfinity(), Double.IsNaN()
doubleがOverflowするとInfinityという値を取ります。ここらへんはMSDNのDoubleに詳しく書いてあります。で、それの判定はDouble.IsPositiveInfinity(double d)です。NaNについても同様。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;    //Threadクラスで必要

namespace WindowsFormsApplication43
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            Thread t = new Thread(
                delegate()
                {
                    for (int x = 0; x < 480; x++)
                    {
                        //中央は(240, 240)
                        double __x = x;
                        double _x = (__x - 240.0d) / 240.0d;

                        for (int y = 0; y < 480; y++)
                        {
                            double __y = y;
                            double _y = (__y - 240.0d) / 240.0d;

                            Complex v = new Complex(_x, _y);

                            //発散しない
                            if (IsDivergence(v) == -1)
                            {
                                if(this.IsHandleCreated)
                                {
                                    this.Invoke(
                                        (MethodInvoker)delegate()
                                        {
                                            Graphics g = this.CreateGraphics();
                                            g.FillRectangle(Brushes.Black, x, y, 1, 1);
                                            g.Flush();
                                            g.Dispose();
                                            label1.Text = x.ToString();
                                            label1.Show();
                                        });
                                }
                            }
                                //早い発散
                            else if (IsDivergence(v) > 0 && IsDivergence(v) < 40)
                            {
                                if (this.IsHandleCreated)
                                {
                                    this.Invoke(
                                        (MethodInvoker)delegate()
                                        {
                                            Graphics g = this.CreateGraphics();
                                            g.FillRectangle(Brushes.Aqua, x, y, 1, 1);
                                            g.Flush();
                                            g.Dispose();
                                            label1.Text = x.ToString();
                                            label1.Show();
                                        });
                                }
                            }
                                //中くらいの発散速度
                            else if (IsDivergence(v) >= 40 && IsDivergence(v) < 70)
                            {
                                if (this.IsHandleCreated)
                                {
                                    this.Invoke(
                                        (MethodInvoker)delegate()
                                        {
                                            Graphics g = this.CreateGraphics();
                                            g.FillRectangle(Brushes.Blue, x, y, 1, 1);
                                            g.Flush();
                                            g.Dispose();
                                            label1.Text = x.ToString();
                                            label1.Show();
                                        });
                                }
                            }
                                //遅い発散
                            else
                            {
                                if (this.IsHandleCreated)
                                {
                                    this.Invoke(
                                        (MethodInvoker)delegate()
                                        {
                                            Graphics g = this.CreateGraphics();
                                            g.FillRectangle(Brushes.RoyalBlue, x, y, 1, 1);
                                            g.Flush();
                                            g.Dispose();
                                            label1.Text = x.ToString();
                                            label1.Show();
                                        });
                                }
                            }
                        }
                    }
                });
            t.Start();
        }

        private int IsDivergence(Complex initval)
        {
            //初期値
            Complex z = new Complex(0.0d, 0.0d);  //z0 = 0

            for (int i = 0; i < 10000; i++)
            {
                z = z * z + initval;
                //catch (OverflowException ex)
                //{
                    //発散
                //    return true;
                //}

                if (Double.IsPositiveInfinity(z.re) || Double.IsPositiveInfinity(z.im))
                {
                    //発散
                    return i;
                }
                else if (Double.IsNaN(z.re) || Double.IsNaN(z.im))
                {
                    //発散
                    return i;
                }
            }
            //発散してない
            return -1;
        }
    }
}
Read more →

2011/08/13

うつくしい基板

,
Read more →

2011/04/25

フィラメント管 ИВ-9

,
Nixie-tube.comさんから、新商品のフィラメント管 ИВ-9を買ってみました。ニキシー管と違い、4V程度の低電圧でも点灯できるのが魅力的です。しかしなんといっても、今のLEDデバイスにはない、温かな光に魅せられました。
時計にしようかと思っています。


Read more →

2011/04/07

WARNING: Application does not specify an API level requirement!の対処法[Android SDK]

,
タイトルの通りです。Androidアプリを開発しようとしたら、
WARNING: Application does not specify an API level requirement!
とでて、エミュレータでアプリが起動できません。

Google先生によると、AndroidManifest.xmlで<uses-sdk>の値を設定すればいいみたいです。

以下のブログが参考になりました。
はじめてのAndroidを読み始めました - So Many People, So Many Different Ideas
http://d.hatena.ne.jp/skelton_boy/20091007

リファレンスは
<uses-sdk> - ソフトウェア技術ドキュメントを勝手に翻訳
https://sites.google.com/a/techdoctranslator.com/jp/android/guide/manifest/uses-sdk-element

APIレベルの設定は、
1. Android API レベル - ソフトウェア技術ドキュメントを勝手に翻訳
https://sites.google.com/a/techdoctranslator.com/jp/android/appendix/api-levels
を参考にしてください。自分はAndroid 2.2をターゲットにしたアプリ(Hello,worldだけど)をつくっていたので、API Levelは8にしました。
Read more →