n_shinichi’s blog

日々の備忘録、 趣味のあれこれなど紹介 (すみません、メニュー、リンク、カテゴリー分けがうまくできてません、★記事一覧★で見てください...) NHK魔改造の夜ではDンソーのベテランアドバイザーってことで出ました♪

MENU

ボディはちょいと削らないとうまく部品が収まらないもんで・・・  初音ミクちゃんカー

 最初から実はわかってたこと・・・だけど、

 ミクちゃんカーにそのまま全部の部品は収まらない。

 

先回の写真でボディーつけたけどマイコンは入らんかった。

 なもんでやたら肉厚で頑丈なボディーはちょいと削り込むことにしたので

 一旦、ボディーなしでミクちゃん乗っけて、電池しょってみた。

 

 

 

これはこれでメカミクちゃんって感じで悪くないかもなんて思った。

 

 

ちょっとミクちゃんに走ってもらった。

 

 

駆動輪のグリップアップで旋回性を上げた。 初音ミクちゃんカー

直進しかさせてくれない補助輪のグリップが駆動輪と同じだと

上手く曲がれんので駆動輪にゴム系接着剤、スーパーXを薄く塗って

ゴムタイヤ風にしてみた。

 

ミクちゃんが持ってるのはハンドルじゃなくてコネクタ・・・

 ボディつけたらESP-01が入らん。。。 どうしたもんか...

いい感じのグリップになったので超信地旋回もできるように

ソフトをちょっと変えた。。。

ちょっと・・・って言ってもちょっと面倒だった。

 

DRV8830を使うと単純なスイッチ切り替えのL9110とかと違って

コイル間の電圧を直接制御できるので(実際にはPWMで分圧だけど)パルスとか

意識せずにベクトル制御とかマイクロステップ駆動もそんなに難しくなくできる。

けど、動かしてみるとハーフステップ駆動でもXYベクトルの大きさ合わせてやると

そこそこ滑らかに回ったのでマイクロステップとかはやってない。

 

その代わりに制御がI2Cなもんで割込みの中で動かすにはちょっと具合悪い。

ただ車輪のダイレクトドライブとかならプロペラをぶんぶん回すみたいな

高回転じゃないのでポーリングでも制御が十分できる。

低回転でゆっくり電圧変えるならそんなに困らない。。。けど、

最初の作り込みが甘かった。

2個のモータを同じ方向に回転させるのは簡単にできるようにしちゃったもんだから

片方が逆回転だとややこしくなってしまった。

 

 

他人が見ても???だと思うけど、おぼえ・・・

 これまでのいろいろロボのつぎはぎでとりあえずのテスト・・・に

  付け足し、付け足しなんでいけてない。。。

 

//  _1
// 
// _2 モータ2個独立して動かせるようにする 
//      M5stickからの受信データは一桁配列番号:0~9、 送信データは2桁番号 10~
//    joy_x:[1],  joy_y[2]                        count[11],  Batt[12]    
//
//  _3    joy_x:1   joy_y:2  で独立駆動テスト  値が -100 ~ 100  +のみ使って一方向回転でまずテスト
//                位相時間の最小値は 103-joy値 :3ms としてみる。
//
//  _4   逆回転もマップ反転処理を入れて対応
//             一応、2個モータ独立で反対回転もjoyコントローラでできるようになった。
//
//  _5 回転の変化がリニアじゃないのでリニア風にしてみる
//   _5a  コメントゴミのある程度整理
//
//   _6 モータをミクちゃんに左右逆に付けてしまったので ベースマップのR側を反転マップにした
//      
//   _7 モータドライバ基板小さく切ったやつは具合悪くてオリジナル基板でミクちゃんに組付けたら前後、左右が逆になってしまった
//    _5aの回転方向で、左右を入れ替え 
//
//
//   _8 超信地旋回検討
//         joyy 10以下 で joyxが50以上になれば信地旋回始める
//
//
#include <ESP8266WiFi.h>
#include <espnow.h>
#define CHANNEL 0
#define LED 2

#include <Wire.h>
// 共立DRV8830、2個モジュール デフォルト設定アドレス
#define MOTOR_L 0x63 //A0=high, A1=open    8bitベースアドレス:0xC6 --- 7-1bit値変換で0x63  IC1側
#define MOTOR_R 0x65 //A0=low,  A1=open     8bitベースアドレス:0xCA --- 7-1bit値変換で0x65  IC2側 

//共立DRV8830、2個モジュール  ★JP1ショート★ A1:GND設定時
#define MOTOR_L2 0x60 //A0=high, A1=open   
#define MOTOR_R2 0x62 //A0=low,  A1=open 

uint8_t slaveAddress[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // ブロードキャスト
unsigned char recvData[100];
static int8_t sendData[100];
ADC_MODE(ADC_VCC);

unsigned long ms10,ms100,ms200,ms500,ms1000,ms2000;
int8_t Batt,Batt_old,count;

int16_t L[10],R[10],L_base[10],R_base[10];
int dir = 1,motor_sw,plus_delay;
uint8_t M_power,dir1,dir2;
float k_plus=1.0,step_gain =1.0;
int8_t temp;

unsigned long plus_t_old,plus_t_old2,shin_delay_old;
int ph_No,ph_No2,p_delay=100,p_delay2=100,shin_delay=100;

int joy_x,joy_y,joy_y_old;
float v_power1,v_power2,balance;

void setup() {
 setupESPNOW();

  Wire.pins(0, 2);  // GPIO 0 and 2 on ESP-01
  Wire.begin(0, 2); // 0=sda, 2=scl
  Wire.setClock(400000);

 

//ハーフステップマップ

L_base[0]= 100; R_base[0]=   0;
L_base[1]=  71; R_base[1]=  71;
L_base[2]=   0; R_base[2]= 100;
L_base[3]= -71; R_base[3]=  71;
L_base[4]=-100; R_base[4]=   0;
L_base[5]= -71; R_base[5]= -71;
L_base[6]=   0; R_base[6]=-100;
L_base[7]=  71; R_base[7]= -71;

  for(int i=0; i<8; i++){
   L[i]=L_base[i]; R[i]=  R_base[i];
  }

 plus_delay = (int)(p_delay*k_plus);

delay(2000);
 ms10=ms100=ms200=ms500=ms1000=ms2000=millis();
}

void loop() {

     if (joy_y != 0){
        if(ph_No  > 7) ph_No  = 0;   // 0 - 7 
        if(ph_No2 > 7) ph_No2 = 0;   // 0 - 7   
     //////////////////////////////////////////////////////////////////////

        if(abs(joy_y) > 10){
     
            if( millis() > (plus_t_old  + p_delay  ) ){      
                drvStep(MOTOR_L2 ,(int16_t)(L[ ph_No  ]*step_gain));
                drvStep(MOTOR_R2 ,(int16_t)(R[ ph_No  ]*step_gain)); 
                plus_t_old  = millis();
                ph_No++;
            }

            if( millis() > (plus_t_old2 + p_delay2 ) ){      
                drvStep(MOTOR_L,(int16_t)(L[ ph_No2 ]*step_gain));
                drvStep(MOTOR_R,(int16_t)(R[ ph_No2 ]*step_gain)); 
                plus_t_old2 = millis();
                ph_No2++;
            }
            
        }
        else{
            if( abs(joy_x) > 50 ){ // 超信地旋回
                shin_delay  = (103 - abs(joy_x)   );

                if( millis() > (shin_delay_old  + shin_delay  ) ){
                          
                    if(joy_x > 0) for(int i=0; i<8; i++) R[i]=  -R_base[i];// 正回転マップ
                    else          for(int i=0; i<8; i++) R[i]=   R_base[i];// 逆回転マップ
                    drvStep(MOTOR_L2 ,(int16_t)(L[ ph_No  ]*step_gain));
                    drvStep(MOTOR_R2 ,(int16_t)(R[ ph_No  ]*step_gain));
                    
                    if(joy_x > 0) for(int i=0; i<8; i++) R[i]=   R_base[i];// 逆回転ップ
                    else          for(int i=0; i<8; i++) R[i]=  -R_base[i];// 正回転マップ                    
                    drvStep(MOTOR_L,  (int16_t)(L[ ph_No  ]*step_gain));
                    drvStep(MOTOR_R,  (int16_t)(R[ ph_No  ]*step_gain));

                    
                    shin_delay_old  = millis();
                    ph_No++;
                }     
                
            }
        }
      //////////////////////////////////////////////////////////////////////
      }
      else{
                drvStep(MOTOR_L , 0); drvStep(MOTOR_R , 0);
                drvStep(MOTOR_L2, 0); drvStep(MOTOR_R2, 0);
      }
    
    if (millis() >  ms100){
      joy_x = recvData[1]-100; 
      joy_y = recvData[2]-100; 

////// パルス位相変化時間を直線単純に反比例・・・これだと最後に急に速くなる感じになる。
//      p_delay  = (103 - abs(joy_y)   ) ;
//      p_delay2 = (103 - abs(joy_y)   ) ;

////// 非線形にしてみた  ///////////////////////////////////////////////
      if( joy_y != 0 ){
         p_delay  = (int)( 1.0/(float)abs(joy_y) *300.0 );
         p_delay2 = (int)( 1.0/(float)abs(joy_y) *300.0 );     
      }

        if( joy_x > 20){ 
          p_delay  = p_delay  + joy_x * joy_x *  0.002 ;
        }
        if( joy_x < 20){
          p_delay2 = p_delay2 + joy_x * joy_x *  0.002 ;
        }

      if( (joy_y_old >= 0) && (joy_y < 0) ){
        for(int i=0; i<8; i++) R[i]=  -R_base[i];// 正回転マップ
      }
      if( (joy_y_old <= 0) && (joy_y > 0) ){ 
        for(int i=0; i<8; i++) R[i]=   R_base[i];// 逆回転マップ
      }
      joy_y_old = joy_y;
            
    ms100+=100;
    }

    if (millis() >  ms1000){   //ESPNOW 返信/////////////////////////
        Batt = ESP.getVcc()*0.01;//  受信側でx0.1で V       
//      if( Batt_old != Batt){
           sendData[12] = Batt;       // 0.1V分を桁上げ
           esp_now_send(slaveAddress, (uint8_t*)sendData, 100);
//      }  
//      Batt_old = Batt; 

        count++;
        sendData[11] = count;
    ms1000+=1000; 
    }

    
}

void setupESPNOW(){
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    esp_now_init();
    esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
    esp_now_register_recv_cb(onRecv);
//    esp_now_peer_info_t peerInfo={};
//    memcpy(peerInfo.peer_addr, slaveAddress, 6);
//    peerInfo.channel = CHANNEL;
//    peerInfo.encrypt = false;
//    esp_now_add_peer(&peerInfo);   
}

void onRecv(uint8_t* mac_addr, uint8_t* on_RecvData, uint8_t len) {
    for (int i=0; i<len; i++) recvData[i] = on_RecvData[i];
}


////// DRV8830 ///////////////////////////////////////////////////////////////////

void drvStep(byte adr, int16_t pwr) { //pwr -100 to 100
  byte dir, st;
  pwr = constrain (pwr, -100, 100);
  if (pwr < 0) dir = 2;
  else dir =1;
  byte ipower=(byte) (abs(63*pwr*0.01));
  if (ipower == 0) dir=0; //惰性
//if (ipower == 0) dir=3; //ブレーキ
  st = drv8830read(adr);
  if (st & 1) drv8830write(adr, 0, 0);
  drv8830write(adr, ipower, dir);
}


void drv8830write(byte adr, byte pwm, byte ctrl) { // pwm 6~3F、ctrl 0:フリー 1:正転 2:逆転 3;ブレーキ
  Wire.beginTransmission(adr);
  Wire.write(0);
  Wire.write(pwm*4+ctrl);
  Wire.endTransmission(true);
}
int drv8830read(byte adr) {
  Wire.beginTransmission(adr);
  Wire.write(1);
  Wire.endTransmission(false);
  Wire.requestFrom((int)adr, (int)1, (int)1);
  return Wire.read();
}

 

 

 

初音ミクちゃんカー、シャーシに無理やり電池、マイコン乗っけて走らせてみた。

シャーシって書いてて思った。

 模型的にはシャーシが自然な感じ。。。

  子供のころからタミヤのプラモデルとかそうだったしミニ4駆でもそう言うし。

 

でも、仕事関係、、自動車業界では標準はシャシー・・・だな。

 

電池、マイコンを押しながら動けてたのでシャーシに乗っけてもちゃんと動く

よな・・・って思ってた。

で、やってみると動輪のトルク、、、パワーは十分かなってとこだけど

思った以上に動きが悪い。

 

元の初音ミクちゃんカーには、第3受動輪、補助輪もなくてみな同じ。

今回前側の左右2輪を動輪で作った。

 

普通?よくある2輪カー、以前作って紹介したライントレーサーとかは

ベースは2輪で作ってる。

でも補助輪、車輪でもなく補助支え...とかはグリップは全然しないようにしてて

転回動作を邪魔しないようにしてる。

 

それがミクちゃんカーだと後ろ1輪の補助輪は動輪と同じ。

なもんで常に直進しようとする...展開を邪魔する。

これじゃうまく曲がれん。。。

 

その状況がこちらの動画。

 

信地旋回とかはできない。

動輪のグリップを上げないといかん。。。

 

 

 

モータドライブ基板、調子こいて小さく切りすぎてた・・・  オリジナルでやり直し。。。

モータドライバ、DRV8830が2個実装してる共立の基板、

 スルーホールのとこで切って、大外の部品ギリで切って小さくしたら...

 よく見てなかったけどスルーホールの外側で配線パターンが

 迂回してるとこなどあって動かなくなってた...

 ジャンパ戦で繋いで直してたらごちゃごちゃして高さが増えてしまった。

 

なもんで一旦、オリジナル基板のままで作り直した。




重ね高さは前と同じ。面積が増えてしまった。

ま でもどっちかというと厳しいのは高さなんでよしとして。。。

でもミクちゃんボディに入れるのはやっぱし厳しいな・・・

 一旦はこのまま作って、次は、、、

 フレームを基板で作ってドライバを実装したの作る だなぁ。

 そしたらミクちゃんボディ被せるのもなんてことなくなるし。

 

でもって動作テストがこちら。

 やっぱしプラスチックのタイヤよく滑る。。。

 でも、ESP-01、電池を押しながらでも脱調せず動ける。

 この分なら思いボディ載せても走れるかな・・・?

 

 

 

 

 

 

 

いい感じに作業できる工具がないので作った。

ミクちゃんカー 作る では

 設計図もなくて勘で現物合わせでやってるので組んで適当なとこで

 ワイヤーをカットしたりしたい。

 

小さく組み換え中のミクちゃんカーフレーム周り。

 


AWG34番のジャンパー線、
ふつうのワイヤストリッパーでは周りがでかすぎて

切りたい位置で切れない、被覆く剥けない。。。

 

AWG34番被覆剥き部が先端になるように工具を加工しました。

 

拡大するとこんな感じ・・・

もうAWG何番かわかんなくなってるけど

 

これで狭いところに突っ込んで被覆剥きができます♪

ミクちゃんカー 車輪付けて動作テスト 

ミクちゃんカー にステッピングモータが付けられるように細工したとこへ

タイヤを取り付けて搭載した。

 

 

こちらはオリジナルのミニカー状態フレーム

 

でもって、動作確認したのがこちら。

黄色い印はタイヤの回転がわかるようにつけてる。

ちょっと回転差がつく感度が高過ぎる感じかな。

またそれは別途調整。

 

 

 

 

 

ChatGPT に 勝ったかも♪ なんて思ったこと。

ChatGPTが何かと話題で電子工作でもすごく便利って話を聞く。

Arduinoでも何々がしたいのだけどサンプルスケッチ教えてって聞くと、

けっこう難しい割込み使ってどうこうってスケッチを

数十秒でサンプル出してくれる。ちゃんと動く。

すごすぎる。。。

 

で、ちょっとひねりが効いたようなこともできるのか聞いてみた。

 

以前自分が作ったTC78H653を使って3相ステッピングモーター

ステッピングモータのように回す... ができるか?

 

結果はできません。 だった。

 でも自分はできた。仕様書に載ってない使い方はChatGPTには

 できないってことになるみたい。

 

 

以前自分が作ったTC78H653を使って3相ステッピングモーター

ステッピングモータのように回す...  はこちら。