###c
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);
  //setPwvWidth0311(1024);
  //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 ASIA
//#define D51
//#define C57103
#define C575xHK800
//#define DD51
//#define DD51K
//#define DE15
//#define DF200
//#define KIHA40
//#define KIHA100 //KATO
//#define KIHA120
//#define KIHA181x5
//#define KIHA183
//#define KIHA187
//#define KTR8000
//#define Renfe592

#ifdef ASIA
  int vIdleMax =  5; int vIdleAcc = 25; int vAccDiv = 2;  int vIdleDelay = 64;
#endif
#ifdef D51
  int vIdleMax =  1; int vIdleAcc = 2; int vAccDiv = 4;  int vIdleDelay = 64;
#endif
#ifdef C57103
  //int vIdleMax =  1; int vIdleAcc = 2; int vAccDiv = 4;  int vIdleDelay = 64;
  int vIdleMax =  5; int vIdleAcc = 25; int vAccDiv = 2;  int vIdleDelay = 64;
#endif
#ifdef C57xHK800
  int vIdleMax =  5; int vIdleAcc = 2; int vAccDiv = 3;  int vIdleDelay = 64;
#endif

#ifdef DD51
  int vIdleMax =  5; int vIdleAcc = 25; int vAccDiv = 3;  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 KIHA40
  int vIdleMax = 10; int vIdleAcc = 12; int vAccDiv = 9;  int vIdleDelay = 32;
#endif
#ifdef KIHA100
  int vIdleMax =  5; int vIdleAcc = 15; int vAccDiv = 6;  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 = 4;  int vIdleDelay = 64;
#endif
#ifdef KIHA187
  int vIdleMax =  8; int vIdleAcc = 30; int vAccDiv = 4;  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

double liner(double ival, double imin, double imax, double omin, double omax)
{
  if (ival < imin) return omin;
  if (ival > imax) return omax;
  
  double irange = imax - imin;
  double orange = omax - omin;
  double rate = orange / irange;
  double oval = rate * (ival - imin) + omin;
  return oval;
}


bool idlingState = true;
int steamCount = 10;
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 (true) {
    Serial.print(value*0);
    Serial.print("\t");
    Serial.print(acc);
    Serial.print("\t");
    Serial.println(vPowerButton.vState);
    Serial.print("\t");
    Serial.println(steamCount);
  }

  if (vPowerButton.vState && acc > vIdleMax) {
    if (--steamCount == 0) {
      int vLapidAcc = 243;
      double vMaxStream = 12;
      double ka = (vMaxStream - 2) / (vIdleAcc - vLapidAcc);
      double kb = vMaxStream - ka * vIdleAcc;
      //steamCount = 3;
      steamCount = ka * acc + kb;
      steamCount = (int)liner(acc, 30, 40, 10, 3); // C575xHK800
      //steamCount = 3;

      
      if (steamCount < 1) steamCount = 1;
      //acc = acc * 30/8;
      acc = acc * 35/20;
      if (false) {
        Serial.print(acc);
        Serial.print("\t");
        Serial.print(steamCount);
        Serial.println("");
      }
    }
      //acc /= 2;
      if (vDirButton.vState) {
        analogWrite(pPwm1, 0  );
        analogWrite(pPwm2, acc);
      } else {
        analogWrite(pPwm2, 0  );
        analogWrite(pPwm1, acc);
      }
  }
  else 
  {
    analogWrite(pPwm2, acc);
    analogWrite(pPwm1, acc);
  }
  delay(vIdleDelay/1);
}
###
    鉄道 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS