2025年07月07日

AKI80でCP/M(その4)デルタ変調でメモリダンプ読上げ


1.はじめに
 国会図書館のサイトでアスキー出版のエンサイクロペディア・アスキーvolume6を見ていたら246ページに「ソフトウェア・スピーチ・シンセサイザー」の記事を見つけました。デルタ変調のデータを使ってマイコンで音声合成を試みる内容の記事です。
 学生頃にこのデルタ変調のデータをダンプリストから入力して自作のZ80マイコンで試したことがあります。このデルタ変調による音声合成については「PSGでのPCM再生に関する考察」の記事で書いたようにネット上のMSXエミュレータ環境であるMSXPenでも動かしました。
 丁度、AKI80でCP/Mが動くようになり、デジタル出力が簡単に使えるようになったのでラダー型の簡易的なD/A変換を使ってAKI80で再度試みてみることにしました。


2.環境構築
 実験環境は極めて簡単で、AKI80のポートAの出力をブレッドボード上に組んラダー型のD/A変換器に接続し、D/Aの出力をポータブルスピーカに接続しました。

AKI80改とラダー型D/Aに接続したスピーカ


3.ソフトウェア
 前述の記事と同じことをやったのでは面白みがないので、今回はメモリダンプを読み上げるプログラムを作ることにしました。
 デルタ変調による音声合成処理は前述のMSXPen環境での実験時に作成したものを使い、メモリダンプ部分はGAME言語で作成しました。

メモリダンプ読上げ処理(GAME言語)
1'+++++++++++++++++++++++++++++++ 2' speech test for Aki80 3' Ver 0.01 2025/07/06 skyriver 4'+++++++++++++++++++++++++++++++ 10 M=&+1 A=M+$10 B=A+$10 20 M(0)=$2100 M(1)=B M(2)=$02CD M(3)=$01 M(4)=$C9 30*-1ZE-4RO 31*I+2TI 32*NII 33*+1SA+0/ 34*+3YO+20/ 35*-1GOO 36*RO+2KU 37*+2NA+0NA 38*HA+3TI 39*+1KI+0U 40*+4E+2I 41*+2BI+0I 42*+2SI+0I 43*+4DE+2E 44*+1I+0I 45*+2E+0FU 50 I=0,9 A:I)=I+$30 @=I+1 52 I=10,15 A:I)="A"+I-10 @=I+1 100 P== C=0 110 @ "" 113 / ?(4)=P:0)*256+P:1) ":" 120 ;=P:2)="*" B(C)=P+3 " " ??=B(C) C=C+1 130 P=P+2 @ P=P+1 @=(P:-1)=0) 140 @=(C=16) 150 #=10000 199'**Wait 200 Z=0,1000 @=Z+1 ] 299'** speech hex(nibble) E <- data 300 ;=(E<0)*(E>15) ] 310 M(1)=B(E) >=M 320 ] 399'** speech hex(1byte) D <-data 400 E=D/16 !=300 410 E=%(D/16) !=300 420 ] 499'** dump 500 /"Dump Memory Reader Ver 0.01 20250706 by skyriver"/ 510 "Start" S=? ;=S=-1 ] 520 "End " F=? 530 @ 540 / ??=S " : " D=S/256 !=400 D=%(S/256) !=400 !=200 550 @ D=S:0) ?$=D " " !=400 S=S+1 !=200 @=((%(S/16)=0)+(S-1=F)) 560 @=(S-1=F) 570 // #=510 599'** speech 0-F demo 600 /" *** hex voice test ***"/ 610 I=0,15 "" 620 M(1)=B(I) $=A:I) >=M 630 !=200 640 @=I+1 650 ] 10000 >=$0100 10010 // !=600 / 10020 !=500

 下図は今回作成したメモリダンプ読上げプログラムを実行している際の画面キャプチャです。今ではWindows上等で高品質な音声合成が可能なので、今回は実験という意味合いでの実装としプログラム開始時に内部データの取得状態等をモニタするために色々表示しています。

メモリダンプ読上げ実行画面例


4.評価結果
 ピッチ(音声の高さ)を変更をせずに平坦な音声にすると合成音を識別するのが難しい状況でした。しかし、ピッチ制御も行い、ヘキサ文字それぞれに特徴的な音程設定を行えば、人間の方が慣れてくるにつれて合成音の判別が可能になりましたw

 X(旧Twitter)に投稿したメッセージに添付した動画も貼っておきます。




[TOP] [ 前へ ] 連載記事一覧 [ 次へ ]

posted by skyriver at 00:19| Comment(0) | Z80 | このブログの読者になる | 更新情報をチェックする

2025年06月29日

Z80での全メモリ同一値設定処理


1.はじめに
 散歩中にZ80のクイズを思いついたのでX(旧Twitter)で問いかけてみました。
 いつもはタイムラインに流れてくる課題(お題)について考える側の人間ですが、たまにはお題の提起をしてみようと思った次第です。あまり反応はないだろうと思っていましたが、予想に反して具体的なコードを示してくれる人もいらして楽しかったと同時に小規模な募集ではありましたが出題する側の大変さも実感しました。



2.お題の内容
 今回のお題の内容は上記のメッセージに書いてあるように下記のとおりです(Xのリンクは後でリンク切れになることがあったので念のために再掲)。

全メモリがRAMのZ80で全メモリを00hにするプログラムはPUSHやRSTを使って作ることができます。
それではPUSHもRSTも使わずに全メモリを同じ値にするプログラムを作れるでしょうか?

 メモリをゼロクリアするプログラムは例えば下記のようなものです。
 尚、以降に掲載するリストはAKI-80用モニターROM&Cコンパイラーセットの購入」の記事で書いたコンパイラに添付されているアセンブラの出力です 講談社のBLUE BACKSシリーズ「動かしながら理解するCPUの仕組み」に添付されているZ-Visionに同胞のアセンブラ(XA80W)の出力です。※訂正 2025/06/29

全メモリクリアプログラム例(Z80アセンブラ)
                        ;++++++++++++++++++++++++
                        ; Z80 all memory clear
                        ;  2025/06/27 skyriver
                        ;++++++++++++++++++++++++
                        
[0000] :                	ORG	0000H
                        
[0000] : 21 01 00       START:	LD	HL,0001H
[0003] : 36 E9          	LD	(HL),0E9H	; JP (HL)
[0005] : 2B             	DEC	HL
[0006] : 36 E5          	LD	(HL),0E5H	; PUSH HL
[0008] : F9             	LD	SP,HL
[0009] : E9             	JP	(HL)
                        
                        	END

 PUSH や RST を使用すれば2バイトでメモリを書き換えるループ処理を作成でき、PUSH もしくは コールスタック で一度に2バイトを書き換えることが可能なことから2バイトのループを一度に上書きできます。
 そこで PUSH や RST を使わないことを条件にしました。流石にこの条件下で全メモリをクリアするのは回答が1方式に集中しそうなので「全メモリを同じ値にする」というように条件を和らげたお題にしました。


3.考える上でのポイント
 今回のお題ではメモリ書き換え部分のプログラム自身も削除する必要があるので効率よくメモリを書き換える必要があります。
 そのためには次の3つの方向から検討できるのではないかと思います。
  1. ブロック転送方式
     2バイト命令であり、この命令単独でループ処理が可能なので多くの人が最初にこの方式を思い浮かべるのではないでしょうか。今回のようにゼロクリアでなくてもいいのであればできそうですね。

  2. コールスタック方式
     コール時の戻りアドレスのスタックへの書き込みを利用する方式で一度に2バイトの書き換えができます。コール処理のアドレス次第で戻り値を決定できるのでメモリを満たすデータは 00h でも可能になるはずです。

  3. 単純ループ方式
     メモリフルするデータを00h以外でも可としたことでこの方式でも可能そうです。


4.回答案
 上記のポイントに沿って事前に考えた回答案は次の3つです。

  1. ブロック転送方式
     ブロック転送命令を利用したサンプルが下記になります。ブロック転送命令の後半のバイトである B0h をアドレスが増加する方向にコピーしていって、ブロック転送命令の最初のバイトの EDh が B0h に書き換えられた直後にブロック転送命令が終了します。
     結果として全メモリが B0h(OR B)で満たされた状態になります。

    Z80全メモリ同値設定プログラム(ブロック転送方式)
                            ;++++++++++++++++++++++++++++++++++
                            ; Z80 fill memory(LDIR method)
                            ;  Ver 0.01 2025/06/27 by skyriver
                            ;++++++++++++++++++++++++++++++++++
                            
    [0000] :                	ORG	0000H
                            
    [0000] : 21 0A 00       START:	LD	HL,CPCODE
    [0003] : 11 0B 00       	LD	DE,CPCODE + 1
    [0006] : 01 00 00       	LD	BC,0
    [0009] : ED             LOOP:	DB	0EDH	; LDIR
    [000A] : B0             CPCODE:	DB	0B0H	;
                            
                            	END
    


  2. コールスタック方式
     FFFDh に自分自信をコールするコール命令を設定し、実行します。コール命令の直前からアドレスが減少する方向に戻り値である 0000h がスタックに積まれていくようにします。最後にコール命令自体が CD FD 00 に上書きされますが 00FDh 以降コール命令までが既に 00h(NOP)なのでコール命令が実行され CD FD も 00 00 に上書きされます。
     結果として全メモリが 00h(NOP)で満たされた状態になります。

    Z80全メモリ同値設定プログラム(コールスタック方式)
                            ;++++++++++++++++++++++++++++++++++
                            ; Z80 fill memory(CALL method)
                            ;  Ver 0.01 2025/06/27 by skyriver
                            ;++++++++++++++++++++++++++++++++++
                            
    [0000] :                	ORG	0000H
                            
    [0000] : 21 FD FF       START:	LD	HL,0FFFDH
    [0003] : 22 FE FF       	LD	(0FFFEH),HL
    [0006] : 36 CD          	LD	(HL),0CDH
    [0008] : F9             	LD	SP,HL
    [0009] : E9             	JP	(HL)
                            
                            	END
    


  3. 単純ループ方式
     HL レジスタを使った4バイトのメモリ書き込みループにより、ループ直前のメモリからアドレスが減少する方向に 77h が設定されていきます。ジャンプ命令が上書きされても連続する 77h を実行してループの先頭まで辿り着きます。
     77h に 77h が上書きされてもメモリ変化はないので、最後に 2Bh が 77h に置き換わります。
     結果として全メモリが 77h で満たされた状態になります。

    Z80全メモリ同値設定プログラム(単純ループ方式)
                            ;++++++++++++++++++++++++++++++++++++
                            ; Z80 fill memory(simple loop method)
                            ;  Ver 0.01 2025/06/27 by skyriver
                            ;++++++++++++++++++++++++++++++++++++
                            
    [0000] :                	ORG	0000H
                            
    [0000] : 21 05 00       START:	LD	HL,LOOP
    [0003] : 3E 77          	LD	A,77H	; LD (HL),A
    [0005] : 2B             LOOP:	DEC	HL
    [0006] : 77             	LD	(HL),A
    [0007] : 18 FC          	JR	LOOP
                            
                            	END
    


    ★追記 2025/07/01
     1バイト短縮してみました。

    Z80全メモリ同値設定プログラム その2(単純ループ方式)
                            ;++++++++++++++++++++++++++++++++++++
                            ; Z80 fill memory(simple loop method)
                            ;  Ver 0.02 2025/07/01 by skyriver
                            ;++++++++++++++++++++++++++++++++++++
                            
    [0000] :                	ORG	0000H
                            
    [0000] : 21 04 00       START:	LD	HL,LOOP
    [0003] : 3E             	DB	3EH	; LD A,xx
    [0004] : 77             LOOP:	LD	(HL),A
    [0005] : 2B             	DEC	HL
    [0006] : 18 FC          	JR	LOOP
                            
                            	END
    

    ※追記 2025/07/02
     開始位置変更&処理時間の増大を許容すれば6バイトに短縮可能 Xのリンク
    ※追記 2025/07/03
     3Eh ⇒ 7Eh でも動きますね。


5.予想外だった回答
 Xで予想外の回答を頂いたので記録しておきたいと思います。以下の回答はタイムラインでの時系列順に記載しています。
 尚、本クイズに寄せられた回答は冒頭のXでの問い掛けメッセージに対するリプライ及び、「引用を表示」(寧ろ引用での回答の方が多い)を表示することで確認できます。
※Xでの回答の確認方法を追記 2025/06/30

  1. 書き込み処理コピー方式 Xのリンク
  2.  前述の「単純ループ方式」では HL を使ったメモリ書き込み処理をループで実行しましたが、この方式ではループ実行ではなく、書き込み処理自体を多数コピーした後に書き込み処理を実行するというように2段階で処理が実行されます。
     一つの書き込み処理が2バイトで新たに1バイトのメモリが設定されるのでメモリを周回する度に書き込み処理の総バイト数の1/2のサイズのメモリが設定されていきます。書き込み処理が残存する間はメモリ書き込みが継続されるので最終的には全ての書き込み処理が上書きされます。
     更に特徴的なのは複数の書き込み処理を最初に実行する際に書き込まれるメモリ領域には書き込み処理をコピーする必要が無いことから、書き込み処理をコピーするためのブロック転送時に B レジスタのみを設定することで処理自体のサイズを1バイト短くしている点です。

    Z80全メモリ同値設定プログラム(書き込み処理コピー方式)
    [0000] :                	ORG	00000H
                            
    [0000] : 21 0B 00       START:	LD	HL,ST
    [0003] : 11 0D 00       	LD	DE,ST+2
    [0006] : 06 FE          	LD	B,0FEH
    [0008] : 7E             	LD	A,(HL)
    [0009] : ED B0          	LDIR
    [000B] : 77             ST:	LD	(HL),A
    [000C] : 23             	INC	HL
                            
                            
                            	END
    



  3. EX (SP),HL方式 Xのリンク
     スタックを使った2バイト書き込みには PUSH, CALL 以外もあることを見落としていましたorz
     本方式はブロック転送後に残った2バイトをEX命令を使って消し去る方式です。
     ブロック転送により末尾にある 00h がアドレスが増える方向にコピーされていき、メモリを一周してブロック転送の前半のバイト(EDh)を00hに書き換えた直後にブロック転送命令から抜け出します。この時点で HL が0000hになっていて、 残った B0 E3 がEX命令により 00 00 に書き換えられます。
    ※動作説明を追記 2025/06/30
     尚、下記のソースは僭越ながら当方でコンパクト化したものです。

    Z80全メモリ同値設定プログラム(EX (SP),HL方式)
    [FFF4] :                	ORG	0FFF4H
                            
    [FFF4] : 21 03 00       START:	LD	HL,CPCODE
    [FFF7] : 11 04 00       	LD	DE,CPCODE+1
    [FFFA] : 01 00 00       	LD	BC,0
    [FFFD] : 31 01 00       	LD	SP,CPCODE-2
    [0000] : ED B0          	LDIR
    [0002] : E3             	EX	(SP),HL
    [0003] : 00             CPCODE:	NOP
                            
                            
                            	END
    


posted by skyriver at 21:26| Comment(0) | Z80 | このブログの読者になる | 更新情報をチェックする

2025年06月09日

AKI80でCP/M(その3)PIO試験


1.はじめに
 秋月さんの秋葉原店で¥280 で特売されているスーパーAKI80がX(旧Twitter)で話題になっています。以前購入した AKI80ゴールドを発掘し、20ピンのPICを使ってCP/Mが動くように改造し、タイマ割込みを使った割込みが問題なく動いたことを前回の記事で書きました。
 今回はPIO(CPUに内蔵されているパラレルインターフェース)の動作確認について書いてみたいと思います。


2.PIO機能
 CPU(TMPZ84C015)に内蔵されたPIOは同シリーズの別チップだったPIOをほぼそのまま1チップ化したもので2チャンネルのパラレルインターフェース機能があります。
 下図はPIO機能のブロック図です(タイポってますね⇒最下行のDiagaram)。

PIOのブロック図(TOSHIBAのデータシートから抜粋)

 PIOには次の4つのモードがあります。
  1. モード0:ハンドシェイク方式のバイト出力
  2. モード1:ハンドシェイク方式のバイト入力
  3. モード2:ハンドシェイク方式のバイト入出力(ポートAのみ可)
  4. モード3:ビットモード
 今回の動作試験ではモード3を使用します。このモードはビット単位で割込み指定可能で複数ビットでのand/or条件も指定できるので外部からの信号に対する割込みコントローラ的に使用することも可能です(今回の試験ではPIOの割込みは使用しません)。


3.試験内容
 先日、AliExpressさんで格安のマイクロサーボ(SG90)を見つけ購入しましたので、今回の試験ではZ80でマイクロサーボを動かしてみたいと思います。Z80でサーボを動かす日が来るとは思ってもいませんでした。Lチカならぬサボグル(サーボをグルグル回す)ですねw

マイクロサーボ(SG90)

 サーボモータは下図のように20ms程の周期のPWM信号で制御可能です。

サーボモータの制御(SG90のデータシートから抜粋)



4.サーボ制御
 PWM機能の無いZ80で制御できるのでしょうか?
⇒タイマ割込みを使えば割合簡単に制御できます。制御信号の生成方法に関しては「PIC24FJで4足ロボットの製作」の記事を参照してください。

 今回は3つのタイマ割込みとPIOの全出力を使い、16個のマイクロサーボの制御信号の生成にチャレンジしてみました。サーボの制御信号はタイマ割込み処理によってバックグラウンドで生成されるので、アプリケーション側ではサーボ制御用の変数を変更するだけでサーボを自由に動かすことができます。

 下図は今回作成したサーボ制御信号の出力例です。図中のそれぞれのタイミングマーカーは
  • P0:PWMの周期
  • P1:最短パルス幅
  • P2:最長パルス幅
  • P3:パルス幅の中央値
  • P4:隣接するチャンネル間の時間差
です。

サーボモータの制御信号例

 サーボ制御信号発生処理部のソースも貼っておきます。

サーボ制御信号生成処理(Z80アセンブラ)
;++++++++++++++++++++++++++++++++++++ ; AKI80 serbo control test ; Ver 0.01 2025/06/06 by skyriver ;++++++++++++++++++++++++++++++++++++ .LIST 0023 SETTIM EQU 00100011B ; CTC mode enable int,timer,pre:256 0080 INTBIT EQU 10000000B ; enabke interrupt 0004 TIMBIT EQU 00000100B ; set timer value next 0000' ASEG ORG 0100H 0100 18 25 START: JR Init ; initialize CTC & PIO 0102 18 5D EXIT: JR StopInt ; stop interrupt 0104 80 00 Serbo0: DB 80H,00H ; PIOA0 serbo pulse width and adjust 0106 80 00 Serbo1: DB 80H,00H ; PIOB0 0108 80 00 Serbo2: DB 80H,00H ; PIOA1 010A 80 00 Serbo3: DB 80H,00H ; PIOB1 010C 80 00 Serbo4: DB 80H,00H ; PIOA2 010E 80 00 Serbo5: DB 80H,00H ; PIOB2 0110 80 00 Serbo6: DB 80H,00H ; PIOA3 0112 80 00 Serbo7: DB 80H,00H ; PIOB3 0114 80 00 Serbo8: DB 80H,00H ; PIOA4 0116 80 00 Serbo9: DB 80H,00H ; PIOB4 0118 80 00 SerboA: DB 80H,00H ; PIOA5 011A 80 00 SerboB: DB 80H,00H ; PIOB5 011C 80 00 SerboC: DB 80H,00H ; PIOA6 011E 80 00 SerboD: DB 80H,00H ; PIOB6 0120 80 00 SerboE: DB 80H,00H ; PIOA7 0122 80 00 SerboF: DB 80H,00H ; PIOB7 0124 0104 SerbPt: DW Serbo0 0126 01 PerBit: DB 1 ; period bit value ; initialize CTC, PIO and work area 0127 F3 Init: DI 0128 ED 5E IM 2 012A 3E 01 LD A,high IntVec 012C ED 47 LD I,A 012E CD 0141 CALL IniCtc 0131 CD 014E CALL IniPio 0134 21 0104 LD HL,Serbo0 0137 22 0124 LD (SerbPt),HL 013A 3E 01 LD A,1 013C 32 0126 LD (PerBit),A 013F FB EI 0140 C9 RET ; initialize CTC 0141 3E C8 IniCtc: LD A,low IntVec 0143 D3 10 OUT (CTCCH0),A ; set vector addr 0145 3E A7 LD A,SETTIM OR INTBIT OR TIMBIT 0147 D3 10 OUT (CTCCH0),A 0149 3E 78 LD A,120 ; 12.288*1000000/256/120=400[Hz] = 2.5ms 014B D3 10 OUT (CTCCH0),A 014D C9 RET ; initialize PIO 014E 21 015E IniPio: LD HL,PINIDAT 0151 E5 PUSH HL 0152 01 031D LD BC,PINILEN * 256 + PIOACMD 0155 ED B3 OTIR 0157 E1 POP HL 0158 01 031F LD BC,PINILEN * 256 + PIOBCMD 015B ED B3 OTIR 015D C9 RET 015E PINIDAT: 015E CF DB 11001111B ; mode3(bit mode) 015F 00 DB 00000000B ; all bits are output 0160 07 DB 00000111B ; no interrupt 0003 PINILEN EQU $ - PINIDAT ; stop CTC int 0161 StopInt: 0161 3E 03 LD A,00000011B ; reset channel 0163 D3 10 OUT (CTCCH0),A 0165 F3 DI 0166 C9 RET ; timer interrupt ; pulse width 1.5 +/ 0.8[ms] ; 2.5ms : 120 96 ; (255*(1/2-1/8)+24)/120*2.5 = 2.49[ms] ; 1.5ms : 72 48 ; 0.5ms : 24 0 0018 LOWOFST EQU 24 ; lowest value offset 0167 IntCtc0: 0167 F5 PUSH AF 0168 C5 PUSH BC 0169 E5 PUSH HL 016A 3E A7 LD A,SETTIM OR INTBIT OR TIMBIT 016C D3 11 OUT (CTCCH1),A 016E D3 12 OUT (CTCCH2),A 0170 2A 0124 LD HL,(SerbPt) 0173 7E LD A,(HL) 0174 CB 3F SRL A 0176 47 LD B,A 0177 E6 FC AND 0FCH 0179 0F RRCA 017A 0F RRCA 017B 90 SUB B 017C ED 44 NEG 017E C6 18 ADD A,LOWOFST ; add serbo senter value 0180 23 INC HL 0181 86 ADD A,(HL) ; add adjust 0182 23 INC HL 0183 D3 11 OUT (CTCCH1),A 0185 7E LD A,(HL) 0186 CB 3F SRL A 0188 47 LD B,A 0189 E6 FC AND 0FCH 018B 0F RRCA 018C 0F RRCA 018D 90 SUB B 018E ED 44 NEG 0190 C6 18 ADD A,LOWOFST ; add serbo senter value 0192 23 INC HL 0193 86 ADD A,(HL) ; add adjust 0194 23 INC HL 0195 D3 12 OUT (CTCCH2),A 0197 3A 0126 LD A,(PerBit) ; get bit pattern 019A D3 1C OUT (PIOADAT),A 019C D3 1E OUT (PIOBDAT),A 019E 07 RLCA 019F 30 03 JR NC,IntC010 01A1 21 0104 LD HL,Serbo0 01A4 IntC010: 01A4 22 0124 LD (SerbPt),HL 01A7 32 0126 LD (PerBit),A 01AA E1 POP HL 01AB C1 POP BC 01AC F1 POP AF 01AD FB IntNul: EI 01AE ED 4D RETI ; CTC ch1 interrupt ; (serbo pulse off 01B0 IntCtc1: 01B0 F5 PUSH AF 01B1 3E 23 LD A,SETTIM ; disable int, not set timer value 01B3 D3 11 OUT (CTCCH1),A 01B5 AF XOR A 01B6 D3 1C OUT (PIOADAT),A ; set serbo pulse off 01B8 F1 POP AF 01B9 FB EI 01BA ED 4D RETI 01BC IntCtc2: 01BC F5 PUSH AF 01BD 3E 23 LD A,SETTIM ; disable int, not set timer value 01BF D3 12 OUT (CTCCH2),A 01C1 AF XOR A 01C2 D3 1E OUT (PIOBDAT),A ; set serbo pulse off 01C4 F1 POP AF 01C5 FB EI 01C6 ED 4D RETI ORG ($+0007H) AND 0FFF8H 01C8 IntVec: 01C8 0167 DW IntCtc0 01CA 01B0 DW IntCtc1 01CC 01BC DW IntCtc2 01CE 01AD DW IntNul END

 また、AKI80 のピンヘッダに出ているPIO出力をマイクロサーボへ接続するために、下図のようなサーボ用ハブを作成しました。

サーボ用ハブ

 下図は今回作成したサーボ用ハブを使ってAKI80にマイクロサーボを接続した状態の写真です。上記のサーボ制御信号発生処理を使ってGAME言語でサーボの試験処理を記述し、動かしました。

マイクロサーボとAKI80


 X(旧Twitter)に投稿したメッセージに添付した動画を貼っておきます。最初の4個は手持ちであったもので動作音が大きいようです。5番目以降のサーボは最近購入(昨日着荷)したものでケース内のギアにグリスがたっぷりと塗布されていて最後のサーボだけ動作音が大きめです。最初と最後のサーボは動きも渋いようですね。ソフトウェア的にはオフセット調整機能もあるのですが、大きくずれている個体は無かったのでオフセット調整は行っていません。

★追記 2025/06/10 {
 動画をよく見るとサーボの動きが激しくなるとサーボ用ハブの緑LEDの光が弱くなっています。これは安定化電源の電流制限により供給電圧が低下している状況だと思われます。電流制限の値を2.5Aから3.0Aに変更したところ、全てのサーボが正常に動くようになりました。
}




[TOP] [ 前へ ] 連載記事一覧 [ 次へ ]

posted by skyriver at 18:13| Comment(0) | Z80 | このブログの読者になる | 更新情報をチェックする