* Pulse Width Modulation(パルス幅変調)制御 [#eb3dc03c]

* モータードライバ: TA8428K [#d0431e69]
- http://akizukidenshi.com/download/ta8428k(s).pdf

|*#|*Name    |*Arg    |*Func         |
|*1|##IN1  ##|##i1 ##|制御用入力端子|
|*2|##IN2  ##|##i2 ##|^             |
|*3|##OUTA ##|##o1 ##|〜1.5A        |
|*4|##GND  ##|##gnd##|GND           |
|*5|##OUTA~##|##o2 ##|              |
|*6|##---- ##|##-- ##|              |
|*7|##Vcc  ##|##vcc##|VCC〜30V      |

|     |    |lx: |     |lx:   |c
|*Mode|*IN1|*IN2|*OUTA|*OUTA~|
|*制動| H  | H  | L   |  L   |
|*正転| H  | L  | H   |  L   |
|*逆転| L  | H  | L   |  H   |
|*停止| L  | L  | Z   |  Z   |

|C[10  uF]|水色106|
|C[ 0.1uF]|水色104|

* ハード [#j705136e]
### verilog
;pin ctrl.gnd = driver.gnd = 0V
;pin ctrl.vcc = 5V
;pin driver.vcc = 12V

;C[10  uF](driver.gnd, driver.vcc)
;C[ 0.1uF](driver.gnd, driver.vcc)

;Arduino ctrl
;TA8428K driver

;driver.i1 = ctrl.D3
;driver.i2 = ctrl.D11

;pin driver.o1;
;pin driver.o2;
###

* ソフト [#f78cb14d]
### C
void setup() {
  Serial.begin(9600);
  pinMode( 3, OUTPUT);
  pinMode(11, OUTPUT);
}

int c1 =  3;
int c2 = 11;
int t = 100;
int d =  50;
int command = 0;
void loop() {

  if (Serial.available() > 0) {
    command = Serial.read();
  }

  digitalWrite(c1, LOW )
  digitalWrite(c2, HIGH)
  delay(d);

  digitalWrite(c1, LOW)
  digitalWrite(c2, LOW)
  delay(t-d);
}
###

*** ディーゼル [#x2389d6e]
###
int iAna0 =  0;
int pPwm1 =  3;
int pPwm2 = 11;

int base = 0;

#define avelg 2
#define avesz (1<<avelg)
int avebf[avesz];
int avelc=0;
int ave=0;

int Ave(int value) {
  ave -= avebf[avelc];    avebf[avelc] = value >> avelg;
  ave += avebf[avelc];

  avelc++;
  if (avelc == avesz) avelc = 0;

  return ave;
}

void setPwvWidth0311(int r) {
  TCCR2B &= B11111000;
  switch(r) {
    case    1:  TCCR2B |= B00000001;  break;
    case    8:  TCCR2B |= B00000010;  break;
    case   32:  TCCR2B |= B00000011;  break;
    default  : 
    case   64:  TCCR2B |= B00000100;  break;
    case  128:  TCCR2B |= B00000101;  break;
    case  256:  TCCR2B |= B00000110;  break;
    case 1024:  TCCR2B |= B00000111;  break;
  }
}

void setup() {
  Serial.begin(9600);
  
  setPwvWidth0311(1024);

  pinMode(pPwm1, OUTPUT);
  pinMode(pPwm2, OUTPUT);
  
  pinMode( 8, OUTPUT);
  pinMode( 9,  INPUT);
  pinMode(10, OUTPUT);
  
  analogWrite(pPwm1, 0 );
  analogWrite(pPwm2, 0 );
  
  digitalWrite( 8,  LOW);
  digitalWrite(10, HIGH);

  base = analogRead(iAna0)+10;
  Serial.print("base == ");
  Serial.println(base);
  
  for(int i = 0; i<avesz; i++) {
    avebf[i] = 0;
  }
}
 
void loop() {
  int sw    = digitalRead(9);
  int value = analogRead(iAna0);
  int ave = Ave(value);
  int acc   = 0;
  
  
  if (sw == LOW) {
    acc = (1024-ave)/4;
  }
  else {
    acc = (ave - base)/2;
    if (acc <  5) acc =   0;
    if (acc >254) acc = 254;
  }
  if (1) {
    Serial.print(value);
    Serial.print("\t");
    Serial.print(ave);
    Serial.print("\t");
    Serial.println(acc);
  }
  
  analogWrite(pPwm1, 0 );
  analogWrite(pPwm2, acc);
  delay(100);
}
###

*** [#g8acfab8]
###
int iAna0 =  1;
int iAna1 =  2;
int pPwm1 =  5;
int pPwm2 =  6;
int pLed1 =  3;
int pLed2 =  9;

int base0 = 0;
int base1 = 0;

#define avelg 2
#define avesz (1<<avelg)
int avebf[2][avesz];
int avelc[2] = {0,0};
int ave[2] = {0,0};

int Ave(int id, int value) {
  if (id > 2) return 0;
  ave[id] -= avebf[id][avelc[id]];    avebf[id][avelc[id]] = value >> avelg;
  ave[id] += avebf[id][avelc[id]];

  avelc[id]++;
  if (avelc[id] == avesz) avelc[id] = 0;

  return ave[id];
}

const int vBaseOffset = 10;
void setup() {
  Serial.begin(9600);

  pinMode(pPwm1, OUTPUT);
  pinMode(pPwm2, OUTPUT);
  pinMode(pLed1, OUTPUT);
  pinMode(pLed2, OUTPUT);

  analogWrite(pPwm1, 0);
  analogWrite(pPwm2, 0);

  base0 = analogRead(iAna0) + vBaseOffset;
  base1 = analogRead(iAna1) + vBaseOffset;
  Serial.print("base == ");
  Serial.print(base0);
  Serial.print(", ");
  Serial.println(base1);

  for (int i = 0; i < avesz; i++) {
    avebf[0][i] = 0;
    avebf[1][i] = 0;
  }
}

int gSwtchingLock = false;
int gDir = 0;
void loop() {
  int value0 = analogRead(iAna0);
  int value1 = analogRead(iAna1);
  int ave0 = Ave(0, value0);
  int ave1 = Ave(1, value1);
  

  int acc = (int)((ave0 - base0) * 0.7);
  if (acc <   5) acc =   0;
  if (acc > 254) acc = 254;

  bool sw = (ave1 - base1) > base1;
  if (gSwtchingLock == false && sw == true && acc == 0) {
    gDir = 1 - gDir;
    gSwtchingLock = true;
  }
  
  if (gSwtchingLock == true)
  {
    Serial.print((gDir == 0) ? "200\t100\t" : "100\t200\t");
    Serial.println(gDir);
    if (sw == false) gSwtchingLock = false;
    return;
  }

  if (gSwtchingLock) {
    analogWrite(pPwm1, 0);
    analogWrite(pPwm2, 0);
    delay(10);
    return;
  }

  if (true) {
    Serial.print(ave0);
    Serial.print("\t");
    Serial.print(ave1);
    Serial.print("\t");
    Serial.println(acc);
  }

  if (gDir == 1) {
    analogWrite(pPwm1, 0 );
    analogWrite(pPwm2, acc);
    analogWrite(pLed1, 0 );
    analogWrite(pLed2, acc);
  }
  else {
    analogWrite(pPwm1, acc);
    analogWrite(pPwm2, 0);
    analogWrite(pLed1, acc);
    analogWrite(pLed2, 0);
  }
  delay(100);
}
###

###
int iAna0 =  0;
int pPwm1 =  3;
int pPwm2 = 11;

int pPower = 7;
int pDir   = 9;
int pPowerDir1 =  5;
int pPowerDir2 = 10;


const int PUSHED = LOW;

int base = 0;
 
#define avelg 2
#define avesz (1<<avelg)
int avebf[avesz];
int avelc=0;
int ave=0;

class cStatelessToggleButton
{
  public:
    int vPort;
    bool vState;
    const int PUSHED = LOW;
    void (*vStateChanged)();
  private:
    int vPushed;
  public:
    cStatelessToggleButton(int aPort, void (*aStateChanged)() = NULL)
      : vPort(aPort)
      , vStateChanged(aStateChanged)
    {
      fInit();
    }

    void fInit() {
      vState = false;
      vPushed = false;
      pinMode(vPort, INPUT_PULLUP);
    }
    
    int fUpdate() {
      if (digitalRead(vPort) == PUSHED) {
        if (vPushed == false) {
          vState = !vState;
          vPushed = true;
          if (vStateChanged != NULL) vStateChanged();
        }
      } else {
        vPushed = false;  
        if (vStateChanged != NULL) vStateChanged();
      }
    }
};
void fCtrlStateChanged();
cStatelessToggleButton vPowerButton(pPower, fCtrlStateChanged);
cStatelessToggleButton vDirButton  (pDir  , fCtrlStateChanged);
void fCtrlStateChanged() {
  analogWrite(pPowerDir1, (vPowerButton.vState &&  vDirButton.vState) ?  50 : 0);
  analogWrite(pPowerDir2, (vPowerButton.vState && !vDirButton.vState) ? 128 : 0);
}
bool neutral = false;
cStatelessToggleButton vNeutralButton  (pDir  , [](){neutral = !neutral;});


int Ave(int value) {
  ave -= avebf[avelc];    avebf[avelc] = value >> avelg;
  ave += avebf[avelc];
 
  avelc++;
  if (avelc == avesz) avelc = 0;
 
  return ave;
}
 
void setPwvWidth0311(int r) {
  TCCR2B &= B11111000;
  switch(r) {
    case    0:  TCCR2B |= B00000000;  break;
    case    1:  TCCR2B |= B00000001;  break;
    case    8:  TCCR2B |= B00000010;  break;
    case   32:  TCCR2B |= B00000011;  break;
    default  : 
    case   64:  TCCR2B |= B00000100;  break;
    case  128:  TCCR2B |= B00000101;  break;
    case  256:  TCCR2B |= B00000110;  break;
    case 1024:  TCCR2B |= B00000111;  break;
  }
}
void setPwvWidth0506(int r) {
  TCCR0B &= B11111000;
  switch(r) {
    case    0:  TCCR0B |= B00000000;  break;
    case    1:  TCCR0B |= B00000001;  break;
    case    8:  TCCR0B |= B00000010;  break;
    case   64:  TCCR0B |= B00000011;  break;
    default  : 
    case  256:  TCCR0B |= B00000100;  break;
    case 1024:  TCCR0B |= B00000101;  break;
  }
}
 
void setup() {
  Serial.begin(9600);
  setPwvWidth0311(256);
  //setPwvWidth0506(1);
 
  pinMode(pPwm1, OUTPUT);
  pinMode(pPwm2, OUTPUT);
    
  pinMode(pPowerDir1, OUTPUT);
  pinMode(pPowerDir2, OUTPUT);
  
  analogWrite(pPwm1, 0);
  analogWrite(pPwm2, 0);
  
  analogWrite(pPowerDir1,  50);
  analogWrite(pPowerDir2, 128);

  base = analogRead(iAna0)+10;
  Serial.print("\nbase == ");
  Serial.println(base);
  
  for(int i = 0; i<avesz; i++) {
    avebf[i] = 0;
  }
}
#define HKS9200
//#define DD51
//#define DD51K
//#define DE15
//#define DF200
//#define KIHA20
//#define KIHA40
//#define KIHA75
//#define KIHA100 //KATO
//#define KIHA120
//#define KIHA181x5
//#define KIHA183
//#define KIHA187x4
//#define KIHA187x6
//#define KTR8000
//#define Renfe592
//#define Sanriku36

#ifdef HKS9200
  int vIdleMax = 10; int vIdleAcc = 20; int vAccDiv = 5;  int vIdleDelay = 64;
#endif
#ifdef DD51
  int vIdleMax = 30; int vIdleAcc = 40; int vAccDiv = 4;  int vIdleDelay = 64;
#endif
#ifdef DD51K
  int vIdleMax =  5; int vIdleAcc = 35; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef DE15
  int vIdleMax =  5; int vIdleAcc = 20; int vAccDiv = 4;  int vIdleDelay = 64;
#endif
#ifdef DF200
  int vIdleMax =  5; int vIdleAcc = 30; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA20
  int vIdleMax = 10; int vIdleAcc = 20; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA40
  int vIdleMax = 10; int vIdleAcc = 12; int vAccDiv = 9;  int vIdleDelay = 14;
#endif
#ifdef KIHA75
  int vIdleMax =  8; int vIdleAcc = 30; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA100
  int vIdleMax =  5; int vIdleAcc = 15; int vAccDiv = 4;  int vIdleDelay = 64;
#endif
#ifdef KIHA120
  int vIdleMax = 10; int vIdleAcc = 20; int vAccDiv = 5;  int vIdleDelay = 64;
#endif
#ifdef KIHA181
  int vIdleMax = 30; int vIdleAcc = 10; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA183
  int vIdleMax =  5; int vIdleAcc = 20; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA181x5
  int vIdleMax = 10; int vIdleAcc = 35; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef KIHA187x4
  int vIdleMax =  8; int vIdleAcc = 30; int vAccDiv = 4;  int vIdleDelay = 64;
#endif
#ifdef KIHA187x6
  int vIdleMax =  8; int vIdleAcc = 30; int vAccDiv = 2;  int vIdleDelay = 64;
#endif
#ifdef KTR8000
  int vIdleMax =  8; int vIdleAcc = 12; int vAccDiv = 6;  int vIdleDelay = 64;
#endif
#ifdef Renfe592
  int vIdleMax =  5; int vIdleAcc = 20; int vAccDiv = 3;  int vIdleDelay = 64;
#endif
#ifdef Sanriku36
  int vIdleMax = 5; int vIdleAcc = 20; int vAccDiv = 5;  int vIdleDelay = 64;
#endif

class DCar {
  bool idlingState;

  DCar() {
    idlingState = true;
  }

  void update() {
    
  }
};

bool idlingState = true;
bool enginePower = true;
void loop() {
  int value = analogRead(iAna0);
  int ave = Ave(value);
  int acc   = 0;

  vPowerButton.fUpdate();
  vDirButton  .fUpdate();

  acc = (ave - base) / vAccDiv;
  if (acc > 254) acc = 254;

  if (1) {
    Serial.print(value);
    Serial.print("\t");
    Serial.print(acc);
    Serial.print("\t");
    Serial.println(vPowerButton.vState);
  }

  if (vPowerButton.vState) {
    if (!enginePower) {
      enginePower = true;
      setPwvWidth0311(1024);
    }
  }
  else {
    if (enginePower) {
      enginePower = false;
      setPwvWidth0311(256);
    }
  }
  if (enginePower) {
    if (acc < vIdleMax) { //反転振動
      if (idlingState) {
        analogWrite(pPwm1, vIdleAcc);
        analogWrite(pPwm2, 0      );
      } else {
        analogWrite(pPwm2, vIdleAcc);
        analogWrite(pPwm1, 0      );
      }
      idlingState = !idlingState;
    }
    else {
      if (vDirButton.vState) {
        analogWrite(pPwm1, 0      );
        analogWrite(pPwm2, acc);
      } else {
        analogWrite(pPwm2, 0      );
        analogWrite(pPwm1, acc);
      }
    }
  }
  else 
  {
    if (acc < vIdleMax) {
        analogWrite(pPwm1, 0);
        analogWrite(pPwm2, 0);
    }
    else {
      if (vDirButton.vState) {
        analogWrite(pPwm1, 0      );
        analogWrite(pPwm2, acc * 6/5);
      } else {
        analogWrite(pPwm2, 0      );
        analogWrite(pPwm1, acc * 6/5);
      }
    }
  }
  delay(vIdleDelay);
}
###

    技術 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS