すっかりBLOG更新が途絶えておりました。秋から業務関係、住居関係を一新していまして、ようやく少し落ち着いたところです。

昨日は久しぶりにフルで時間が取れましたので、かねてからやってみたいと思ってい「21世紀の真空管」Nutube6P1を
秋月から買ってきて真空管ラジオを作ってみました。

物はこんな感じです。


動作させると2つの真空管部がほのかに輝くのがなかなか良い感じです。

回路図はこうです。


Nutubeのデータシートとネットで見た真空管ラジオ回路図を参考に組んでみたものです、一応動作していますが真空管はいじったことがないため適切ではないかもしれません。あくまでご参考としてください。

Nutubeはアンプ動作の動画がいくつか上がっており、そこで真空管部が光るのを見ていました。てっきり昔の真空管みたいにフィラメントが光るのだと思っており、最初に150オームを介してフィラメント端子に3.3Vを供給しましたが全く光らずにあせりました。

その後試してみたところ、グリッドとアノードの配線をちゃんとして、グリッドのバイアス電圧も与えると光ることわかりました。
実際にラジオを受信できるようになってから見ていたら音の大きさで光り方が変わっているようです。
そういうものなのか、調整が不十分なので不安定なのか、わかりません。
とりあえず聞こえているし、面白いのでよしと思っています。

動作を動画にしてみました。


動画では音がよろしくないですが、これはセラミックイヤホンを無理にカメラのマイクに寄せて録音したためです。
普通にイヤホンで聞くとかなり音質はよいと思います。

それではまたです。
2016.11.24 Thu l 未分類 l コメント (1) l top
以前ichigojamで動かしてみた100均電子ピアノをなんとかマイコン抜きでオルゴールにしようと考えていまして、ようやくある程度できましたので記事とします。

最初は基板を取り出して細工しようと思っていたのですが、それをやるとキー接点がなかなかうまくできないので、結局ケースのままとして、もとからある鍵盤を活用としました。

こんな感じです。板に丸ピンを刺して楽譜とし、100均電子ピアノにガイドをつけて板の上で動かすと丸ピンで鍵盤が押されます。
板も含めてすべて100均で売っているものです。DAISOさんの取り揃えには感心します。



工作過程と動作は動画をご覧ください。


100均アイテム縛りにしましたので夏休み工作っぽくて時期的に良いかな、と(^^;。


2016.08.14 Sun l 100円ショップ工作 l コメント (3) l top
先週末秋葉原に行った際にAITNDOのFMラジオモジュールFM577-4Pを購入してきました。



I2Cで割と簡単に操作できそうでしたのでICHIGOJAMにつないで実験中です。


aitendoによるとこのモジュール電源は5Vですが、乗っているDSPラジオとアンプICは3Vでも動作できるものでしたので、
ichigojamの3.3Vで動かしています。

このモジュールはTEA5767というチップを乗せています。データシートはこちらです。

このチップのレジスタ構成はちょっと変わっていて、レジスタは5個固定で、レジスタアドレスに相当するものがありません。
どういうことかというと、通常はI2Cではデバイスアドレス、レジスタアドレス、データ1、データ2、。。。
という書き込みをするところ、このチップはデバイスアドレス、データ1、データ2、。。。データ5、となります。
ICHIGOJAMのI2CW命令は、デバイスアドレス、レジスタアドレス、レジスタデータの3パラメータ構成なので少し悩みましたが、結局以下のコードで設定できることがわかりました。

10 POKE #700,#27,#72,#00,#3E,#00
20 A=I2CW(#60,#700,1,#701,4)
30 SLEEP


固定周波数82.5MHzで設定するコードです。詳細は後日解説します。

問題はなぜ30行にSLEEPがいるのか、です。

最初10行と20行だけで動かしてみたのところ、ひどい雑音とかすかな音楽が聞こえてきました。
どうやらI2C設定はできていて、周波数か他の設定が間違っているのだな、と思って
設定値を確認してみたのですが、特におかしいところがない。。。。。

色々試している中で。たまたまCLSで画面を消去すると状態が良くなることがわかりました。
これはノイズ影響だな、と思ってLCDモニタの電源を切ってみても変わりない。。。

次にichigojamのCPUを強制的にリセット状態にすると著しく改善することがわかりました。
どうやらCPU動作のノイズによる模様です。
リセット状態のままでおけないのでSLEEPにしたところやはり改善したので30行に追加しました。

いかしやっぱり画面表示して選局とかしたいのでSLEEPのままとも行きません。
次回はノイズ観測と対策を打ってみたいと思います。



2016.07.26 Tue l ICHIGOJAM l コメント (0) l top
どうやらワイヤフレームで3D表示っぽいことができるようになりました。

その前に苦労した自由ラインルーチンについてはこちらをご覧ください。)



■ワイヤフレーム3Dルーチンは以下です。これを実行すると、#700-#7FFに書き込まれます。

1 poke#700,240,181,133,36,137,176,3,145,36,1,14,25,3,156,164,70,58,73,97,68,6,145,0,36,49,95,4,145,2,36,49,95,5,145,4,36,49,95,140,70,0,41,4,218,75
2 poke#72d,66,27,4,27,20,156,70,84,224,4,156,90,67,97,70,97,67,64,37,84,17,73,17,9,27,67,67,9,4,5,152,9,12,1,145,97,70,65,67,88,17,73,17,9,26
3 poke#75a,9,4,9,12,82,0,91,0,18,4,27,4,2,145,18,20,27,20,145,17,8,4,0,12,7,145,1,0,31,49,9,4,9,12,62,41,35,216,153,17,12,4,36,12,39
4 poke#787,0,23,55,63,4,63,12,46,47,26,216,151,17,127,16,7,151,31,39,9,1,185,67,7,159,127,24,169,33,9,1,127,24,3,153,207,25,2,33,100,0,12,64,1,57
5 poke#7b4,8,64,32,67,129,64,8,0,128,33,73,66,8,67,57,120,1,67,57,112,1,153,138,24,2,153,1,61,203,24,18,4,27,4,45,4,18,20,27,20,45,12,197,209,6
6 poke#7e1,155,6,54,4,154,5,152,158,66,1,208,99,70,146,231,0,32,9,176,240,188,2,188,8,71,192,70,200,8,0,0


■使い方
  [40]-[99]に3ワード単位で描画したいラインのX,Y,Z座標を書き込んで、
  CLSののちに#700をコールすると一気に描画されます。

  [40+3*N] : X座標をー31~+31の範囲で入れます。
  [40+3*N+1] : Y座標をー31~+31の範囲で入れます。
  [40+3*N+2] : Z座標を絶対値0~100くらいで入れます。数字が大きいほど近くなります。
          
  Z座標に線の切れ目を示す仕掛けが入っています。マイナスをつけるとそこが線の区切りになります。
  逆に正の数だと区切りをつけずに一筆書きで描画します。
  例えば [40]=0:[41]=0:[42]=-10 : [43]=10:[44]=0:[45]=10: [46]=10:[47]=10:[48]=10 : [49]=20:[50]=20:[51]=10:
       では(X,Y,Z) = (0,0,10)-(10,0,10)-(10,10,10)-(20,20,10)を一筆書きでつなぎます。
それにたいして [40]=0:[41]=0:[42]=-10 : [43]=10:[44]=0:[45]=10: [46]=10:[47]=10 :[48]= -10 : [49]=20:[50]=20:[51]=10:
       だと(X,Y,Z) = (0,0,10)-(10,0,10) と (10,10,10)-(20,20,10)の2本の線を書きます。
   線分データ量を減らして、自由度を上げるためにこうしています。
   この方式のため、最初の座標のZ([42]は必ずマイナスとしてください。

■制限
  [40]-[99]は使えません。

■デモ3パターンを作ったので動画にしました。



「スポンサードリンク」

style="display:block"
data-ad-client="ca-pub-0620260288102702"
data-ad-slot="9773401572"
data-ad-format="auto">



■デモプログラム1 :回転する3角形

10 CLS:T=0:S=0:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT
50 K=24:[K]=RND(32)-16:[K+1]=RND(24)-12:[K+2]=5:[K+3]=RND(8)
70 FORD=5TO50
80 J=40:K=24:X=[K]:Y=[K+1]:Z=[K+2]:C=[K+3]:IFS=0GSB500ELSEGSB600
90 Z=D*2
100 [K+2]=Z:[K+3]=(C+1)%12
110 CLS:A=USR(#700,0)
135 WAIT 2
140 NEXT
150 T=T+1:IFT>3T=0:S=1-S
170 GOTO 50
500 H=0:I=0:GSB1000:[J]=X+V:[J+1]=Y-5:[J+2]=-(z+W)
520 H=10:I=0:GSB1000:[J+3]=X+V:[J+4]=Y+5:[J+5]=z+W
530 H=-10:I=0:GSB1000:[J+6]=X+V:[J+7]=Y+5:[J+8]=z+W
540 H=0:I=0:GSB1000:[J+9]=X+V:[J+10]=Y-5:[J+11]=z+W
550 RTN
600 H=0:I=-5:GSB1000:[J]=X+V:[J+1]=Y+W:[J+2]=-Z
610 H=10:I=5:GSB1000:[J+3]=X+V:[J+4]=Y+W:[J+5]=z
620 H=-10:I=5:GSB1000:[J+6]=X+V:[J+7]=Y+W:[J+8]=z
630 H=0:I=-5:GSB1000:[J+9]=X+V:[J+10]=Y+W:[J+11]=z
650 RTN
1000 V=(H*[C]-I*[12+C])/10
1010 W=(H*[12+C]+I*[C])/10
1020 RTN


■デモプログラム2 :回転する角錐

10 CLS:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT
50 FORE=0TO1:K=24+E*4:[K]=RND(32)-16:[K+1]=RND(24)-12:[K+2]=5+E*30:[K+3]=RND(8):NEXT
70 FORD=5TO50
80 FORE=0TO1:J=40+E*24:K=24+E*4:X=[K]:Y=[K+1]:Z=[K+2]:C=[K+3]:GSB500
90 Z=Z+2:IFZ>100Z=20
100 [K+2]=Z:[K+3]=(C+1)%12:NEXT
110 CLS:A=USR(#700,0)
135 WAIT 2
140 NEXT:GOTO50
500 H=0:I=-4:GSB1000:[J]=X+V:[J+1]=Y+W:[J+2]=-Z
510 H=4:I=4:GSB1000:[J+3]=X+V:[J+4]=Y+W:[J+5]=Z
520 H=-4:I=4:GSB1000:[J+6]=X+V:[J+7]=Y+W:[J+8]=Z
530 H=0:I=-4:GSB1000:[J+9]=X+V:[J+10]=Y+W:[J+11]=Z
540 H=0:I=0:GSB1000:[J+12]=X+V:[J+13]=Y+W:[J+14]=Z+8
550 H=4:I=4:GSB1000:[J+15]=X+V:[J+16]=Y+W:[J+17]=Z
560 H=0:I=0:GSB1000:[J+18]=X+V:[J+19]=Y+W:[J+20]=-(Z+8)
570 H=-4:I=4:GSB1000:[J+21]=X+V:[J+22]=Y+W:[J+23]=Z:RTN
1000 V=(H*[C]-I*[12+C])/10:W=(H*[12+C]+I*[C])/10:RTN



■デモプログラム3 :キー操作できる立方体
 
 これは上下左右キーでXY方向移動、1・2キーでZ方向移動、3・4キーで回転ができます。

10 CLS:[0]=10:[1]=8:[2]=5:[3]=0:[4]=-5:[5]=-8:[6]=-10:[7]=-8:[8]=-5:[9]=0:[10]=5:[11]=8
30 [12]=0:[13]=5:[14]=8:[15]=10:[16]=8:[17]=5:[18]=0:[19]=-5:[20]=-8:[21]=-10:[22]=-8:[23]=-5
40 FORE=40TO99:[E]=-1:NEXT:C=0:X=0:Y=0:Z=40
100 GSB500:K=INKEY():IFK=51C=C-1:IFC<0C=11
110 IFK=52C=C+1:IFC>11C=0
120 IFK=28ANDX>-32:X=X-1
130 IFK=29ANDX<32:X=X+1
140 IFK=30ANDY>-32:Y=Y-1
150 IFK=31ANDY<32:Y=Y+1
160 IFK=49ANDZ>20:Z=Z-2
170 IFK=50ANDZ<100:Z=Z+2
180 CLS:?"X:";X;" Y:";Y;" Z:";Z;" R:";C:A=USR(#700,0):WAIT2:GOTO100
500 H=-10:I=-10:GSB1000:[40]=X+V:[41]=Y-3:[42]=-(z+W):[55]=X+V:[56]=Y+3:[57]=Z+W
510 H=10:I=-10:GSB1000:J=43:GSB700:H=10:I=10:GSB1000:J=46:GSB700
520 H=-10:I=10:GSB1000:J=49:GSB700:H=-10:I=-10:GSB1000:J=52:GSB700
530 H=10:I=-10:GSB1000:J=70:GSB710:H=10:I=10:GSB1000:J=76:GSB710
540 H=-10:I=10:GSB1000:J=82:GSB710:RTN
700 [J]=X+V:[J+1]=Y-3:[J+2]=z+W:[J+15]=X+V:[J+16]=Y+3:[J+17]=Z+W:RTN
710 [J]=X+V:[J+1]=Y-3:[J+2]=-(z+W):[J+3]=X+V:[J+4]=Y+3:[J+5]=Z+W:RTN
1000 V=(H*[C]-I*[12+C])/10:W=(H*[12+C]+I*[C])/10:RTN


■マシン語ルーチンのソースコード

1行目の<と>は全角になっていますが、お使いになる場合は半角に変えてください。
(FC2ブログ文字化け対策)

#include <stdint.h>
#define VRAM_ADR 0x900 // 画面
#define WORK_ADR 0x800

uint16_t stars(uint16_t c, uint8_t* m_p, uint8_t* f_p)
{
int16_t p,x0,y0,z0,x1,y1,z1,i,x,y,xp,yp,dx,dy,w;
uint8_t c1;
int16_t* w_p = m_p + WORK_ADR; // 変数アドレス獲得
uint8_t* v_p = m_p + VRAM_ADR; // 画面アドレス獲得

p=40;
// x1=0;y1=0;z1=0; //********* メモリ節約のため初期化しない。最初のデータをZ<0とすること。
while (p<100) { //***** 配列[40]-[99]を使用
x0 = x1; y0=y1; z0=z1;
x1 = w_p[p++];y1 = w_p[p++];z1= w_p[p++];
if (z1<0) {
z1 = -z1; //***** Zがマイナスは一筆書きの切れ目を意味する
}else{
dx = ((x1*z1)>>5) - ((x0*z0)>>5); //***** 3D-2D変換後のX座標始点と終点の差分を計算
dy = ((y1*z1)>>5) - ((y0*z0)>>5); //***** 3D-2D変換後のY座標始点と終点の差分を計算
x = ( (x0*z0) << 1); //***** 3D-2D変換後の始点X座標 ((x0*z0)>>5) <<6) 画面座標の64倍
y = ( (y0*z0) << 1); //***** 3D-2D変換後の始点X座標((x0*z0)>>5) <<6) 画面座標の64倍
for (i=0;i<64;i++) { //64回dx、dy加算で線を引く
xp=x>>6; //画面座標にする
yp=y>>6; // 画面座標にする
w=((yp&0xfffe) <<4) + (xp>>1) + 384+16; //*** 変換した座標に対応するVRAMアドレス計算
c1= ( 1 <<( ( ( xp&1) | (yp&1)<<1) ) ) | 0x80; //*********** セミグラフィックキャラ計算
if ( (xp>-32)&&(xp<32)&&(yp>-24)&&(yp<24) ) {v_p[w] |= c1;}
x += dx;
y += dy;
}
}
}
return 0;
}


マシン語256B、BASIC1KBでも結構いろいろできるものです。

それではまたです。

2016.07.02 Sat l ICHIGOJAM l コメント (0) l top
キャラクタ3Dがまあまあ動いたので気をよくして、次は「ワイヤフレーム3Dいってみよう!」ということにしました。

「まずはラインルーチンから」と考えたところで、はたと困りました。

普通にブレゼンハムのアルゴリズムを考えたのですが、これって傾きが1未満と1以上で描画を分けるのですよね。つまり2倍のコードが必要なわけです。始点と終点のX,Y大小関係も考慮が必要です。
これまでの経験上、これはichigojam用としてはメモリが足りないだろう、とわかります。

どうしたものかなあ、と考えていたところ、通勤中の電車内でひらめきました。

  ・ichigojamのセミグラフィックを64x64しかないのを逆手に取り、その範囲にあったアルゴリズムにします。

   ・描画する座標x,yそれぞての始点と終点の差分を取りdx、dyとします。 
   ・描画座標は64倍で計算します。
   ・64倍された始点座標にdx、dyを加算していくと、64回加算でちょうど終点座標の64倍になります。
   ・その加算過程の座標を1/64してドットをうつと、始点から終点にいたる線が描画されます。

これは普通に縦横数百PIXEL以上の画面では演算回数が多くなりすぎて使えないでしょう。
また、短い線だと同じPIXELに何回も無駄に書きます。(極端な話長さ1piexlの線でも同じところに64回点を打ちます。)
64x64しかないから画面でマシン語だから使えるアルゴリズムです。

帰宅して早速C言語にしてみました。

最初の行の<と>は全角ですが、使用する場合は半角の<と>変えてください。
FC2ブログ文字化けを防ぐためにこうしています。


#include <stdint.h>
#define VRAM_ADR 0x900
#define WORK_ADR 0x800

uint16_t stars(uint16_t c, uint8_t* m_p, uint8_t* f_p)
{
int16_t p,x0,y0,x1,y1,i,x,y,xp,yp,dx,dy,w;
uint8_t c1;
int16_t* w_p = m_p + WORK_ADR;
uint8_t* v_p = m_p + VRAM_ADR;

p=0;
while (p<4) {
x0 = w_p[p++];y0 = w_p[p++];
x1 = w_p[p++];y1 = w_p[p++];
dx = x1 - x0;
dy = y1 - y0;
x = x0 << 6;
y = y0 << 6;
for (i=0;i<64;i++) {
xp=x>>6;
yp=y>>6;
w=((yp&0xfffe) <<4) + (xp>>1) + 384+16; //*** 変換した座標に対応するVRAMアドレス計算
c1= ( 1 <<( ( ( xp&1) | (yp&1)<<1) ) ) | 0x80; //*********** セミグラフィックキャラ計算
if ((xp>-32)&&(xp<32)&&(yp>-24)&&(yp<24)&&((v_p[w]&0x70)==0) ) {v_p[w] |= c1;}
x += dx;
y += dy;
}
}
return 0;
}


で、BASICでは以下のコードでテストしてみました。

10 cls
20 for i=-5to5
25 cls
30 [0]=31:[1]=-i:[2]=-31:[3]=i
40 a=usr(#700,0)
45 wait 10
50 next
100 for i=-5to5
110 cls
120 [0]=-i:[1]=-i:[2]=i:[3]=i
130 a=usr(#700,0)
140 wait 10
150 next
200 for i=-5to5
210 cls
220 [0]=-i-5:[1]=-i+5:[2]=i:[3]=i*2
230 a=usr(#700,0)
240 wait 10
250 next


意図通りに線が描画されます。傾きも始点・終点位置関係も問題なしです。

いけるようなので明日はZ座標を導入して3Dのラインを書けるようにします。

その次はいよいよワイヤフレーム3Dです。

それではまたです。


2016.06.29 Wed l ICHIGOJAM l コメント (0) l top