1

Arduinoを使ってプログラミングをしていますが、問題があります。関数では、関数が実行されるたびloop()に、変数に値を追加したいと考えています。私が書いた関数からその値を取得し、コマンドで追加しましたが、機能しません。を印刷すると、常にゼロになります。印刷するとゼロ以外の値が得られますが。コード全体は次のとおりです。pwmloop()pwmpwm += resultpwmresult

float pwm = 0;
float result = 0;

void loop(){

    ....

    errV = w - cm;
    errDtV = errOldV - errV;

    result = flc->cog(errV, errDtV);

    Serial.print("RESULT: ");
    Serial.println(result);

    pwm += result;
    Serial.println(pwm);
}

出力は次のようになります。

RESULT: 31.98
0.00

何が間違っている可能性がありますか?

編集:これが全体のスケッチです

#include "FSet.h"
#include "FRule.h"
#include "Flc.h"
#include <NewPing.h>
#include "MotorControl.h"

MotorControl* m;
Flc* flc;
FRule* rule1,*rule2,*rule3,*rule4,*rule5,*rule6,*rule7,*rule8,*rule9;

NewPing sonar1(32,33,200);

static int dirA = 9;
static int pwmA = 8;

// Setup the FSets
FSet errZ(0,5,0);
FSet errMP(-15,15,0);
FSet errLP(-30,15,-1);

FSet errDtLN(-4,2,-1);
FSet errDtMN(-2,2,0);
FSet errDtZ(0,2,0);
FSet errDtMP(2,2,0);
FSet errDtLP(4,2,1);

FSet cntLN(-40,20,0);
FSet cntMN(-20,20,0);
FSet cntZ(0,20,0);
FSet cntMP(20,20,0);
FSet cntLP(40,20,0);

void setup(){
  Serial.begin(4800); 
  pinMode(dirA,INPUT);

  //Creating FRules for test    
  rule1 = new FRule(&errZ,&errDtMP,&cntMN);
  rule2 = new FRule(&errZ,&errDtZ,&cntZ);
  rule3 = new FRule(&errZ,&errDtMN,&cntMP);
  rule4 = new FRule(&errMP,&errDtLP,&cntMN);
  rule5 = new FRule(&errMP,&errDtMN,&cntMP);
  rule6 = new FRule(&errLP,&errDtMP,&cntMP);
  rule7 = new FRule(&errLP,&errDtZ,&cntLP);  
  rule8 = new FRule(&errLP,&errDtMN,&cntLP);  
  rule9 = new FRule(&errLP,&errDtLN,&cntLP);  

  flc = new Flc(9);
  flc->addRule(rule1);
  flc->addRule(rule2);
  flc->addRule(rule3);
  flc->addRule(rule4);
  flc->addRule(rule5);
  flc->addRule(rule6);
  flc->addRule(rule7); 
  flc->addRule(rule8);
  flc->addRule(rule9); 

}

int errV = 0;
int errOldV = 0;
int errDtV = 0;
int w = 30;
unsigned int uS;
unsigned int cm;

float pwm1 = 0;
float result = 0;

void loop(){   
  uS = sonar1.ping();
  cm = (uS / US_ROUNDTRIP_CM);

  errV = w - cm;
  errDtV = errOldV - errV;    

  result = flc->cog(errV,errDtV);

  Serial.print("RESULT: ");
  Serial.println(result);

  pwm1 = pwm1 + result;  

  Serial.println(pwm1);
  analogWrite(pwmA,pwm1);

  errOldV = errV;

}

FLC クラスヘッダファイル: #ifndef FLC_H #define FLC_H #include "Arduino.h" #include "FRule.h"

class Flc {
    public:
        Flc(int size);
        ~Flc();
        int addRule(FRule* rule);
        int mom(float x1,float x2);
        float cog(float x1,float x2);

        FRule** rules;

    private:
        int last;
        int size;
        float h;
        float numerator = 0;
        float denominator = 0;
        float result = 0;

};

#endif

FLC クラスのソース: #include "Arduino.h" #include "Flc.h"

Flc::Flc(int size){
    this->rules = (FRule**) malloc(sizeof(FRule*) * size);

    this->size = size;
    last = -1;
}

Flc::~Flc(){
    free(rules);
}

int Flc::addRule(FRule* rule){
    this->rules[++last] = rule;
    return last;
}

int Flc::mom(float x1,float x2){
    return 0.0;a
}

float Flc::cog(float x1, float x2){

    for(int i = 0; i < size;i++){

        h = rules[i]->dof(x1,x2);
        float area = rules[i]->widthOfCon() * ( h - h*h/2);

        numerator += rules[i]->cntrOfCon() * area;
        denominator += area;

    }

    result = numerator / denominator;

    return result;


}
4

1 に答える 1

1

関数 cog() の何かが変数 pwm を踏みつけています。float 変数が破損すると、Serial.print() はゼロを表示します。以下のサンプルは、float を 0xffffff に設定すると、浮動小数点演算ライブラリが変数に対する操作を停止することを示しています。

以下のサンプル プログラムを実行すると、一度だけ pwm が正しく出力されることがわかります。最初の不正な呼び出しの後、ゼロが出力されます。また、占有するメモリも変化しなくなりました。

pwm=0.50 zpwm=0.50
pwm=0.00 zpwm=3.95 result=3.45
255-255-255-255
pwm=0.00 zpwm=4.45
pwm=0.00 zpwm=7.90 result=3.45
255-255-255-255

間違ったメモリ位置に書き込む関数を示すサンプル プログラム。リンカーが出力するメモリ マップを見ると、変数はリストされている順序でメモリに配置されます。そのため、var の末尾を超えて書き込むと、pwm が破損します。

float zpwm = 0;
byte var = 0;
float pwm = 0;
float result = 0;


float badactor() {
  *((long*)(&var+1)) = -1;
  return 3.45;
}

void setup() {
  Serial.begin(57600);
}

void loop() {

  zpwm += 0.5;
  pwm += 0.5;

  Serial.print("pwm=");
  Serial.print(pwm);
  Serial.print(" zpwm=");
  Serial.println(zpwm);

  result = badactor();
  pwm += result;
  zpwm += result;

  Serial.print("pwm=");
  Serial.print(pwm);
  Serial.print(" zpwm=");
  Serial.print(zpwm);
  Serial.print(" result=");
  Serial.println(result);

  uint8_t* ptr;
  ptr = (uint8_t*)&pwm;
  Serial.print((int)*(ptr));
  Serial.print("-");
  Serial.print((int)*(ptr+1));
  Serial.print("-");
  Serial.print((int)*(ptr+2));
  Serial.print("-");
  Serial.println((int)*(ptr+3));

  delay(1000);
}
于 2013-02-17T04:55:58.570 に答える