ATmega128 I/Oポートの不思議
ロボファイト4の参加申し込みをしたのに、いまだにソフトウェアが完成していません。
当然モーションデータも0です。
今回の機体では、SISOさんに作ってもらったPWMの分配器を3つ使用します。
以前にM16CからATmega128に移植を始めたころ、この分配器の動作確認をしていたのですが、実際に3つ繋げてオシロ確認してみたら、一つだけ正常に動作しませんでした。
原因をいろいろ調べてみましたがわからず。
ただ、症状としては分配用の信号(3PIN分)の動作が、正常な2つと比べるとメリハリがありませんでした。
どうメリハリがないかというと、HIGHレベル(5V)からLOWレベル(0V)に変わる時に、5V→2V→1V→0Vといった具合にオシロの波形が出ています。正常なほうは5V→0Vといった具合に綺麗に波形が出ていました。
ただ、だとしてもなぜ分配が機能しないのかが理解できないのですが、例によって見なかったことにして、別のポートを使用することにしたところ正常に動作しました。
メリハリのあるI/Oポート
PA3,PA5,PA7
PC1,PC3,PC5
PF2,PF4,PF6
メリハリのないI/Oポート
PC0,PC2,PC4
なんででしょうかね???
ちなみに、分配ができない状態のときに、オシロのプローブ(名前あっているのかな・・・)を分配用の信号に接触させると、たまに分配が機能したり(不安定)しました。これもなぞ。
さて、話は変わりまして第11回ROBO-ONEの競技規則が公開されましたね。
おおむね、”すばらしい”変更だと感じます。
てっきり予選通過は64台なんだと思っていましたが、どうやら32台みたいですね。
「いきなり本選」チケットは一種類みたいだから、当然ですよね。
当然モーションデータも0です。
今回の機体では、SISOさんに作ってもらったPWMの分配器を3つ使用します。
以前にM16CからATmega128に移植を始めたころ、この分配器の動作確認をしていたのですが、実際に3つ繋げてオシロ確認してみたら、一つだけ正常に動作しませんでした。
原因をいろいろ調べてみましたがわからず。
ただ、症状としては分配用の信号(3PIN分)の動作が、正常な2つと比べるとメリハリがありませんでした。
どうメリハリがないかというと、HIGHレベル(5V)からLOWレベル(0V)に変わる時に、5V→2V→1V→0Vといった具合にオシロの波形が出ています。正常なほうは5V→0Vといった具合に綺麗に波形が出ていました。
ただ、だとしてもなぜ分配が機能しないのかが理解できないのですが、例によって見なかったことにして、別のポートを使用することにしたところ正常に動作しました。
メリハリのあるI/Oポート
PA3,PA5,PA7
PC1,PC3,PC5
PF2,PF4,PF6
メリハリのないI/Oポート
PC0,PC2,PC4
なんででしょうかね???
ちなみに、分配ができない状態のときに、オシロのプローブ(名前あっているのかな・・・)を分配用の信号に接触させると、たまに分配が機能したり(不安定)しました。これもなぞ。
さて、話は変わりまして第11回ROBO-ONEの競技規則が公開されましたね。
おおむね、”すばらしい”変更だと感じます。
てっきり予選通過は64台なんだと思っていましたが、どうやら32台みたいですね。
「いきなり本選」チケットは一種類みたいだから、当然ですよね。
塗装
コーネリアスは、ちょっと足のピッチ軸間が長いため、
ひざのサーボに負荷が高くなっておりました。
サーボが焼けたのが1回。
ギアが欠けたのが2回。
今回はピッチ軸間の距離を短くすることを目的に、足を作りなおしました。新しい足のピッチ軸間は7.5cmです。まだ、ちょっと長い気がしますが、デザイン優先ということにしました。
で、今回は以前から行おうと思っていた塗装にチャレンジしました。
でも皆さんのようにスプレーで塗装をする環境が我が家(アパート)にはありませんので、筆でプラカラーを塗りました。
ムラなんて気にしません。塗り残しも気にしません。

効果は良くわかりませんが、金属用のプライマーが売っていたので安かったし(200円也)使ってみました。
効果はどうなんでしょう・・・
で、足を仮組みしてみて分かったこと。
全体的に長すぎです。24cmもあります。
今週末は改良を加えてもう少し短くなるようにがんばってみます。
ちなみに、ロボファイト4までの完成を最優先にすべく、足のヨー軸追加は保留にしました。(T_T)
ひざのサーボに負荷が高くなっておりました。
サーボが焼けたのが1回。
ギアが欠けたのが2回。
今回はピッチ軸間の距離を短くすることを目的に、足を作りなおしました。新しい足のピッチ軸間は7.5cmです。まだ、ちょっと長い気がしますが、デザイン優先ということにしました。
で、今回は以前から行おうと思っていた塗装にチャレンジしました。
でも皆さんのようにスプレーで塗装をする環境が我が家(アパート)にはありませんので、筆でプラカラーを塗りました。
ムラなんて気にしません。塗り残しも気にしません。

効果は良くわかりませんが、金属用のプライマーが売っていたので安かったし(200円也)使ってみました。
効果はどうなんでしょう・・・
で、足を仮組みしてみて分かったこと。
全体的に長すぎです。24cmもあります。
今週末は改良を加えてもう少し短くなるようにがんばってみます。
ちなみに、ロボファイト4までの完成を最優先にすべく、足のヨー軸追加は保留にしました。(T_T)
ATmega128でプレステコントローラと通信
いやー、長かった。
やっとATmega128でプレステ用コントローラ(以下PS2PADと略す)と通信できました。
使っているPS2PADはロジクールの無線のやつです。
いままでM16Cの時もPS2PADとの通信はIOポートをプログラムで叩いて実現しておりました。
ATmega128への移植時も、そのプログラムをそのまま使う予定だったのですが、少々問題が出てきました。
なぜかATmega128処理速度が遅いのです。
M16Cよりもだいぶ遅いです。
プログラムは馬鹿でかいswitch処理があるのみで、case処理の中は数行のプログラムなのですが、1パルス(一回の割り込み)の処理に14μsほどかかります。理想は2μs程度らしい。
switch処理が遅いのは想像が付くので、最適化してみました。
デフォルトの最適化なしが-O0
最高の最適化が-O3みたいです。
写真の矢印の部分の設定を変えました。
[Project]メニューの[Configration Options]を選ぶと開きます。

-O1にしたところ、14μsから10μsまで早くなりました。
-O3にして見ましたが、おなじく10μs程度でした。
どうやらswitch処理の最適化は-O1でも実施されるようです。
しかし、まだ10μs。目標にはだいぶ遠いです。
なんでこんなに遅いのかを調べるのも面白そうですが、ここはSPIってやつを使ってみることにします。
SPIとはSerial Peripheral Interfaceの略で、PS2PADの通信はSPIが使えるらしいです。
じつはIOポートを叩くプログラムを完成させたころ(2年ほど前かな)にどこかのHPで知りました。もう作ってしまったので、わざわざ作り直すことはしてきませんでしたが、SPIだと、もしかしたら早くなるかもしれません。なぜならATmega128にはSPI機能が付いています。
で、実装してみました。
DDRB = _BV(PINB0) | _BV(PINB1) | _BV(PINB2); // 出力
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0) | _BV(DORD) | _BV(CPOL) | _BV(CPHA);
cbi( PORTB, PINB0 ) ; // PAD_SS
wait2(4) ;
SPDR = m_cPadWData[0] ;
loop_until_bit_is_set(SPSR, SPIF);
m_cPadData[0] = SPDR ;
wait2(4) ;
------省略ここから
あと8バイト分くりかえす。
------省略ここまで
sbi( PORTB, PINB0 ) ; // PAD_SS
いままで300行ぐらいあったプログラムが50行程度になりました。
(wait2(4)の行は30μs程度の自前Sleep関数を呼び出しています)
そしてなによりタイマを使用する必要が無いのでタイマが一つ節約できます。
そして速度ですがめちゃ早いです。
上記プログラム例ではFosc/128というもっとも遅い周期を使用しておりますが、十分なほど早いです。
速度は改善されたのですが、まだ通信は出来ませんでした。
原因はPS2PADからの信号の電圧が低すぎて、ATmega128のIOポートではHigh/Lowを認識できないためです。
いろいろなかたのHPをみて調べていると、10k程度のプルアップ抵抗を繋ぐと良いらしい。M16Cの時はそんなことしなくても大丈夫だったので半信半疑だったのですが、手持ちの抵抗をやりくりして10kΩを繋いでみました。
ビンゴ!!
ここまで長かった〜。
さ〜て、アルミ加工アルミ加工。
やっとATmega128でプレステ用コントローラ(以下PS2PADと略す)と通信できました。
使っているPS2PADはロジクールの無線のやつです。
いままでM16Cの時もPS2PADとの通信はIOポートをプログラムで叩いて実現しておりました。
ATmega128への移植時も、そのプログラムをそのまま使う予定だったのですが、少々問題が出てきました。
なぜかATmega128処理速度が遅いのです。
M16Cよりもだいぶ遅いです。
プログラムは馬鹿でかいswitch処理があるのみで、case処理の中は数行のプログラムなのですが、1パルス(一回の割り込み)の処理に14μsほどかかります。理想は2μs程度らしい。
switch処理が遅いのは想像が付くので、最適化してみました。
デフォルトの最適化なしが-O0
最高の最適化が-O3みたいです。
写真の矢印の部分の設定を変えました。
[Project]メニューの[Configration Options]を選ぶと開きます。

-O1にしたところ、14μsから10μsまで早くなりました。
-O3にして見ましたが、おなじく10μs程度でした。
どうやらswitch処理の最適化は-O1でも実施されるようです。
しかし、まだ10μs。目標にはだいぶ遠いです。
なんでこんなに遅いのかを調べるのも面白そうですが、ここはSPIってやつを使ってみることにします。
SPIとはSerial Peripheral Interfaceの略で、PS2PADの通信はSPIが使えるらしいです。
じつはIOポートを叩くプログラムを完成させたころ(2年ほど前かな)にどこかのHPで知りました。もう作ってしまったので、わざわざ作り直すことはしてきませんでしたが、SPIだと、もしかしたら早くなるかもしれません。なぜならATmega128にはSPI機能が付いています。
で、実装してみました。
DDRB = _BV(PINB0) | _BV(PINB1) | _BV(PINB2); // 出力
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0) | _BV(DORD) | _BV(CPOL) | _BV(CPHA);
cbi( PORTB, PINB0 ) ; // PAD_SS
wait2(4) ;
SPDR = m_cPadWData[0] ;
loop_until_bit_is_set(SPSR, SPIF);
m_cPadData[0] = SPDR ;
wait2(4) ;
------省略ここから
あと8バイト分くりかえす。
------省略ここまで
sbi( PORTB, PINB0 ) ; // PAD_SS
いままで300行ぐらいあったプログラムが50行程度になりました。
(wait2(4)の行は30μs程度の自前Sleep関数を呼び出しています)
そしてなによりタイマを使用する必要が無いのでタイマが一つ節約できます。
そして速度ですがめちゃ早いです。
上記プログラム例ではFosc/128というもっとも遅い周期を使用しておりますが、十分なほど早いです。
速度は改善されたのですが、まだ通信は出来ませんでした。
原因はPS2PADからの信号の電圧が低すぎて、ATmega128のIOポートではHigh/Lowを認識できないためです。
いろいろなかたのHPをみて調べていると、10k程度のプルアップ抵抗を繋ぐと良いらしい。M16Cの時はそんなことしなくても大丈夫だったので半信半疑だったのですが、手持ちの抵抗をやりくりして10kΩを繋いでみました。
ビンゴ!!
ここまで長かった〜。
さ〜て、アルミ加工アルミ加工。



