本日からはAKB会員番号11番 電飾用XIAOです♪うそです♪
こいつです。
このXIAOは主に翼端灯などのLEDのコントロールとなっています。
まずは翼端灯
尾翼のライトも
タイマーの動きも問題なし。
次フォーメーションライト!
・・・・・・・・・・・点灯しない。
では手順にのっとってチェック。
まずはロジアナで信号の確認・・・・・OK
XIAOからの端子0の出力確認・・・・・X(ブ~~~ッ!)
プログラム確認・・・・・・anlogWriteで間違っていないのに・・・
念のためdigitalWriteにして書き込んでみました。するとなんか点灯ww
で、offにしようとするとまた反応しないww
でも何度かコマンドを入れると反応することに気が付きました!
I2Cの信号をちゃんと受け取ってないのか???
うむ・・・・レベルシフタ部分も確認・・・問題ないな・・・・・・・・
これは!!もしかして、なおさんが言っていた電圧低下による信号の受け取りミスか??!!
とLEDの電源線を抜いて、さらにプログラム中にシリアルを仕込んで変数の変化を見てみます。
うむw信号を受け取って変数は変化してる。
再度LEDの電源線を繋いで確認。
うんwちゃんと変数は変化しているじゃないw!
なおさんが言っていたような高度な問題ではないようですww
どうもI2Cの通信で信号は受け取っているがその数字に対するアクションがしっかりと起きていない感じ・・・・・。
で、この部分の関数はこうなっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
void ope(){ if(x==21){analogWrite(formation,20);} if(x==22){analogWrite(formation,0);} if(x==23){analogWrite(yokutan,250); tail=1;} if(x==24){analogWrite(yokutan,0); tail=0;} if(x==25){analogWrite(landing_light,250);} if(x==26){analogWrite(landing_light,0);} if(x==27){analogWrite(wing_light,250);} if(x==28){analogWrite(wing_light,0);} if(x==45){digitalWrite(nose_gear,HIGH);} if(x==46){digitalWrite(nose_gear,LOW);} if(x==62){analogWrite(head_laser,250); delay(1500); for(byte i; i<250;i++){ analogWrite(head_laser ,250-i); delay(20); } } if(x==71){mp3_next ();} if(x==72){mp3_prev ();} if(x==73){MP3_vol_up();} if(x==74){MP3_vol_down();} if(x==75){mp3_stop ();} if(x==99){mp3_stop (); analogWrite(formation,0); analogWrite(yokutan,0); tail=0; analogWrite(landing_light,0); analogWrite(wing_light,0); digitalWrite(nose_gear,LOW); analogWrite(head_laser,0); } // Serial.println(x); X=0; } |
このope();という関数がループしているんです。
で、よ~~~く考えてみましたw
I2Cの信号は割り込みでどの時点でも変数xを変化させることが出来ます。
で、上の関数がずっとループしているんです~。
となると、この関数の一番上にあるフォーメーションライトの状態を変化させる信号が来たとして、もし3行目以下の部分で裏でx=21となっても、43行目でX=0とされちゃうんですよwww
そのためループして再度2行目に来た時にはX=0ですので何のアクションも起こせませんw
つまりX=21で2行目でアクションを起こすには、Xは44もしくは1行目の所で信号を受け取っていないといけないですよね~。こんな短い間しか有効な受信時間がないなんてw
だからなかなか信号を受け取ってもアクション起こせなかったんだ~。
アホやなw明らかにプロブラムミスですw
ならば!とプログラムを改変
変数が変化したら、次の信号が来るまでその変数を保持して、1回だけしか実行してほしくない時のみ、そのコマンドを実行したら変数を0に戻すようにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
void ope(){ if(x==21){analogWrite(formation,20);} if(x==22){analogWrite(formation,0);} if(x==23){analogWrite(yokutan,250); tail=1;} if(x==24){analogWrite(yokutan,0); tail=0;} if(x==25){analogWrite(landing_light,250);} if(x==26){analogWrite(landing_light,0);} if(x==27){analogWrite(wing_light,250);} if(x==28){analogWrite(wing_light,0);} if(x==45){digitalWrite(nose_gear,HIGH);} if(x==46){digitalWrite(nose_gear,LOW);} if(x==62){analogWrite(head_laser,250); delay(1500); for(byte i; i<250;i++){ analogWrite(head_laser ,250-i); delay(20); } x=0; } if(x==71){mp3_next ();x=0;} if(x==72){mp3_prev ();x=0;} if(x==73){MP3_vol_up();x=0;} if(x==74){MP3_vol_down();x=0;} if(x==75){mp3_stop ();x=0;} if(x==99){mp3_stop (); analogWrite(formation,0); analogWrite(yokutan,0); tail=0; analogWrite(landing_light,0); analogWrite(wing_light,0); digitalWrite(nose_gear,LOW); analogWrite(head_laser,0); } // Serial.println(x); } |
なんかいっちょ前に書いてますが
要は 変数 x=0; の位置を変えただけですwwまとめて0に戻しちゃおうという安易な考えが原因のミスでしたwでもちょっと勉強になった( ̄^ ̄)ゞ
効果はてきめん!
コマンド送信1回でちゃんと稼働するようになりました^^
それでも端子0出力をanalogWriteにするとうまく出力できないのは変わらず・・・・
仕方ないのでこの端子0はdigitalWriteで使うことにして他の機能に振り分けました。
で、フォーメーションライトは端子6に接続analogWriteで出力できるようになりました。
アナログ出力にこだわるのは、
デジタル出力だとここ明るすぎなんですよね^^;
抵抗仕込むのも面倒なのでアナログ出力で調整w
こんな感じでプログラム上で調整しました。
機首側のフォーメーションライトもオッケ~
でも、実はこの後もう一つのXIAOでもあA0ピンでのアナログ出力が出来ないことに・・・・・
うむ・・・・・なんだ、このA0ピンは????ネット検索してみました。
するとこんな文章を発見
グーグル先生に翻訳してもらってます。
なんかA0ピンのアナログ出力は他とは違うみたいね・・・・・
よく見ると0~1023と書いてあるね!!!!
なるほど!!ほかのピンの出力は0~255で0~3.3Vを出力してくるけど、
A0ピンは0~1023で0~3.3vを出力してるわけね。
つまり今までanalogWrite(A0,250);とか書いていたけど、これでは出力少なすぎてLEDが光っているようには見えなかったのか!
試しにanalogWrite(A0,1000);にしたら点灯しました~!
ピンとLEDの間に15mA用のCRDを挟んでいますが、この場合550位からLEDの点灯が分かるくらいでした。250じゃ全然点灯しないわけですw
これでまた一つ賢くなったw
次はランディングライト!
ココはまだ主脚側は作っていないないので、ノーズギア側のみですが。
おっけ~!
次翼付け根に有るランディングライト。
ココも一発オッケ~!
次はこの部分唯一の動力系ノーズギアのサーボコントロール部分。
ココは元々このようなギミックなっていました。
配線接続でコマンドを入力すると・・・・・・
パチーーーン!!!という音と共に金属棒の先端に接着していたプラパーツがどこかに飛んでいきましたwww
サーボホーンに押されて横からの力に耐えきれずにとれちゃいましたw
まっ瞬着で平面での接着ですから横からの強い力には弱いですよね・・・・・トホホホ^^;
てなことで、今度は金属棒にドリルで穴を開けて
瞬着の先端に穴を開ける虫ピンの先端部分を切断後
先ほどの穴に差し込んで接着整形しました
形は適当ですw
そしてサーボホーンの方も少し形を変更して
側方力が少なくなるように変更しました。
問題はこれで機体が持ち上げられるかですよね~。
以上の形態の変更とサーボの回転軸に近いことも有って
結構機体の重さがかかっているのですが、スムーズに持ち上げていますw
ただ、シャフトが縮んでいる時を通常状態にしてもサーボに少し負荷がかかるのかボチボチの電流を喰っています。
そのため、可動角度を少し大きめにして
サーボに負荷がかからない位置を通常状態としました。これで電流はほぼ0となりました。
この他にこのXIAOは効果音用のDFPlayerも扱うのですが、これえもまた後日サウンドファイルなどを作ってからの調整となります。
よ~し!これで会員番号11番終了ww
関連すると思われる記事:
- None Found
A0にはそんな罠があったんですね。
いつもA0は空けていたので気付きませんでした。
なるほど。むにゃむにゃ、すやすや。ぐご~~。
はっ!!
いい子守歌になりました。僕なら単純に()を増やして試すかな~?
まず第一に極力自己点滅LEDに変えて同調部分はパーツを減らして単純なつくりにもっていくだろうなあ。まっ、そもそもこんな小難しいことができませんが!!!!
サーボモーターも負荷をかけすぎですから、テコの原理でもう一つぐらいシーソーか半月型の
ギヤがあった方が良さげな気はしますね。とかできもしない屁理屈ばかりならべてしまって
ごめんちゃい!!
こんばんは
着実に進行していますね! もう工作のスピードは、マッハクラスです。(羨ましい)
i2cの件ですが、確か割り込み処理でしたね。
PICでも割り込み処理は便利ですが、問題の種でもあります。(経験者は語る!)
私の解決策は、割り込み時にすぐに変数を更新しないで、なにかFLGを立てておき、メインの方で都合の良い時にそのFLGを読みに行って、処理が必要なら処理する、という感じにしています。
あと、メインギアのサーボと丸いパーツの所には少量のグリスを塗布することをお勧めします。
こんにちは
なんかもうシステムが大きすぎて、ブログ読んでてもすご~いと思いながらも想像が追い付きませんw
割込み関数との変数のやり取りは気を使いますよね。完全にやろうと思うと割り込み禁止を設定して変数操作し、そのあと再び割り込み許可、なのですがそこまでやる必要はないのか、あるいは、WIREライブラリがやってくれてるのか?
私の場合(PIC)もVividさんと似た感じでです。
I2C受信の割り込みがかかったら、
割り込み禁止→変数に受信データを保存&新しいデータ受信したフラグをセット(このフラグはバイト変数(ESP32だったら32bit変数までOKなんだと思います)。複数バイトだと実行時に複数命令に別れる可能性があるためNMI多重割込みでおかしくなる可能性があるため)→割り込み許可
使う側で当該フラグが1だったら受信データを使用、それ以外は現状維持、みたいな処理をしてます。
ちなみに、ope()はelse分なしですが、ループ時間が一定になるようにあえてでしょうか?if~elseネストにしたらトータルの処理量は減る方向でCPU負荷は減ると思うのですが。。。
これ、いつも解決済の状態なので、ふむふむとさらりと記事読んでますが、実際は相当な時間と手間がかかっているんですよね。。
想像しただけで、吐きそうですw
6jiroさんには普通かもしれませんが、尾翼灯とかが点滅してるとかっこいいですね~。
gvoさん こんばんは!なぜに「v」www
ええっw
A0端子使ってなかったんですか!!!
gyoさんは解決済みなんだと思っていましたよ~。
そこはちゃんとハマってもらわないとww
teznoさん こんばんは!
そっか~!自己点滅というのもアリでしたね~。
なんか自分で好きなタイミングでと思うと、すぐにタイマー使っちゃいますw
まっ点灯をコントロールするマイコンは必要なのでパーツは増えてないからいいか^^;
サーボモーターは確かに負荷かけ過ぎなんですよね~
~。
なるほど、てこの原理を応用して間にギアなどをかませると良いかもですね。
次からはその辺も考えてサーボ使ってみますね。
今回はあのコクピットモニターの下のスペースという事で限界ギリギリでしたので、
これでご勘弁をw
Vividさん こんばんは!
意外と進んでますwもっと苦労するかと思っていたんですけどね^^;
ホント割り込みはタイミング難しいですよね~。
その辺考えて、今回はサーボとかステップモーターとかはAVRに任せたのですが、単純なタイミングの問題でハマっちゃいましたw
そうですね~I2Cは今回初ですが、赤外線受信の時などは仰るようにフラッグ立てて割り込みでの処理を最低限にしていました。
今回の場合は、割り込みでの処理は受信したら変数xにその数字を代入する処理だけで、このope()関数はメインのループで回してます。
ノーズギア部分にグリス‼了解です(`・ω・´)ゞ
確かにその方がよさそうですね!
ありがとうございます!
なおさん こんばんは!
なんかね、ここまで色々なマイコンを組み合わせて処理するプログラム作ったので色々と苦労していますwwでも動いた時は爽快ですねww
割り込みについてはVividさんの所にも書きましたが、出来るだけ最低限の処理にしています。
で、割り込み許可についてはArduinoが勝手やってくれているので任せっきりですww
今回のXIAOではタイマー割り込みも併用しているのですが、I2C側は何も影響を受けていないみたいです。ほんとarduino様のおかげですじゃ~~~!!
ope()ないのif文にelseがある方が処理が楽なんですね~初めて知りました!if文の羅列になっている理由は簡単す!!プログラムが見やすいからwwwこれだけの理由ですwww
パイロットapaさん こんばんは!
確かにw読まれる方はすらすら進んでいけますもんねww
実際は色々と地獄有りますww
今回のA0ピンについても、実はこの時は分かっていなかったんですよw!
こののちに再度XIAOを使う時が有るのですが、その時に初めて分かりましたw
もうネットで検索しまくりですw
尾翼の点滅とか確かにかっこいいですよね~
飛行機物も電飾が栄えます^^