搜索
bottom↓
回复: 7

请帮忙看一下这个程序报错的问题,急!

[复制链接]

出0入0汤圆

发表于 2013-12-14 18:24:36 | 显示全部楼层 |阅读模式
在arduino 105中提示:
sketch_dec13a:26: error: variable or field 'MoveWheels' declared void
sketch_dec13a:26: error: 'WheelDirection' was not declared in this scope
sketch_dec13a:26: error: expected primary-expression before 'int'


以下是程序

#define __AVR_ATmega328P__
/**
* Self-Balancing Robot
* Kerry D. Wong
* http://www.kerrywong.com
*
* Built with NetBeans IDE
* The I2C library code is from DSSCircuits
* http://dsscircuits.com/articles/arduino-i2c-master-library.html
*/
#include <Arduino.h>
#include <math.h>
#include <I2C/I2C.h>

//<editor-fold defaultstate="collapsed" desc="PIN Defenitions">
const int PIN_GYRO_X = 0; //analog 0
const int PIN_GYRO_Z = 1; //analog 1

const int PIN_MOTOR_1 = 3;
const int PIN_MOTOR_2 = 5;

const int PIN_MODE_SWITCH = 2;
const int PIN_MODE_LED = 6;
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Accelerometer Register Defenitions">
const byte REG_STATUS = 0x00; //(R) Real time status
const byte REG_OUT_X_MSB = 0x01; //(R) [7:0] are 8 MSBs of 10-bit sample
const byte REG_OUT_X_LSB = 0x02; //(R) [7:6] are 2 LSBs of 10-bit sample
const byte REG_OUT_Y_MSB = 0x03; //(R) [7:0] are 8 MSBs of 10-bit sample
const byte REG_OUT_Y_LSB = 0x04; //(R) [7:6] are 2 LSBs of 10-bit sample
const byte REG_OUT_Z_MSB = 0x05; //(R) [7:0] are 8 MSBs of 10-bit sample
const byte REG_OUT_Z_LSB = 0x06; //(R) [7:6] are 2 LSBs of 10-bit sample
const byte REG_SYSMOD = 0x0b; //(R) Current system mode
const byte REG_INT_SOURCE = 0x0c; //(R) Interrupt status
const byte REG_WHO_AM_I = 0x0d; //(R) Device ID (0x3A)
const byte REG_XYZ_DATA_CFG = 0xe; //(R/W) Dynamic range settings
const byte REG_HP_FILTER_CUTOFF = 0x0f; //(R/W) cut-off frequency is set to 16Hz @ 800Hz
const byte REG_PL_STATUS = 0x10; //(R) Landscape/Portrait orientation status
const byte REG_PL_CFG = 0x11; //(R/W) Landscape/Portrait configuration
const byte REG_PL_COUNT = 0x12; //(R) Landscape/Portrait debounce counter
const byte REG_PL_BF_ZCOMP = 0x13; //(R) Back-Front, Z-Lock trip threshold
const byte REG_P_L_THS_REG = 0x14; //(R/W) Portrait to Landscape trip angle is 29 degree
const byte REG_FF_MT_CFG = 0x15; //(R/W) Freefall/motion functional block configuration
const byte REG_FF_MT_SRC = 0x16; //(R) Freefall/motion event source register
const byte REG_FF_MT_THS = 0x17; //(R/W) Freefall/motion threshold register
const byte REG_FF_MT_COUNT = 0x18; //(R/W) Freefall/motion debounce counter
const byte REG_TRANSIENT_CFG = 0x1d; //(R/W) Transient functional block configuration
const byte REG_TRANSIENT_SRC = 0x1e; //(R) Transient event status register
const byte REG_TRANSIENT_THS = 0x1f; //(R/W) Transient event threshold
const byte REG_TRANSIENT_COUNT = 0x20; //(R/W) Transient debounce counter
const byte REG_PULSE_CFG = 0x21; //(R/W) ELE, Double_XYZ or Single_XYZ
const byte REG_PULSE_SRC = 0x22; //(R) EA, Double_XYZ or Single_XYZ
const byte REG_PULSE_THSX = 0x23; //(R/W) X pulse threshold
const byte REG_PULSE_THSY = 0x24; //(R/W) Y pulse threshold
const byte REG_PULSE_THSZ = 0x25; //(R/W) Z pulse threshold
const byte REG_PULSE_TMLT = 0x26; //(R/W) Time limit for pulse
const byte REG_PULSE_LTCY = 0x27; //(R/W) Latency time for 2nd pulse
const byte REG_PULSE_WIND = 0x28; //(R/W) Window time for 2nd pulse
const byte REG_ASLP_COUNT = 0x29; //(R/W) Counter setting for auto-sleep
const byte REG_CTRL_REG1 = 0x2a; //(R/W) ODR = 800 Hz, STANDBY mode
const byte REG_CTRL_REG2 = 0x2b; //(R/W) Sleep enable, OS Modes, RST, ST
const byte REG_CTRL_REG3 = 0x2c; //(R/W) Wake from sleep, IPOL, PP_OD
const byte REG_CTRL_REG4 = 0x2d; //(R/W) Interrupt enable register
const byte REG_CTRL_REG5 = 0x2e; //(R/W) Interrupt pin (INT1/INT2) map
const byte REG_OFF_X = 0x2f; //(R/W) X-axis offset adjust
const byte REG_OFF_Y = 0x30; //(R/W) Y-axis offset adjust
const byte REG_OFF_Z = 0x31; //(R/W) Z-axis offset adjust
const byte I2C_ADDR = 0x1c;
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Accelerometer Scale Defenitions">
const byte FULL_SCALE_RANGE_2g = 0x0;
const byte FULL_SCALE_RANGE_4g = 0x1;
const byte FULL_SCALE_RANGE_8g = 0x2;
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Wheel Directions">
enum WheelDirection {
  DIR_FORWARD,
  DIR_BACKWARD,
  DIR_STOP
};
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Gyro initial value">
float GYRO_X_INIT_VAL = 450.0;
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Other Constants"> */
//gyro: 500 dps
//acc: 2g -256,256
const float INIT_ANGLE = -0.005;
const int ANGLE_BUFFER_LENGTH = 3;
const float SumErrMax = 3;
const float SumErrMin = -3;
//</editor-fold>

// <editor-fold defaultstate="collapsed" desc="Global Variables">
int VxAcc = 0, VyAcc = 0, VzAcc = 0;
int VxGyro = 0, VzGyro = 0;

float degX = 0.0f, degY = 0.0f, degZ = 0.0f;
float throttle = 0.0;

float accAngle = 0.0, currAngle = 0.0, prevAngle = 0.0, elapsedTimeSec=0.0;
unsigned long prevTimeStamp = 0, currTimeStamp = 0, elapsedTime = 0;
boolean isFirstTime = false;

float angleBuffer[ANGLE_BUFFER_LENGTH];
int angleBufferIndex = 0;

boolean MotorOff = false;

float curErr = 0, prevErr = 0, SumErr = 0;
float integralTerm = 0, derivativeTerm = 0;
float Kp = 30000.0, Ki = 50000,  Kd = 500;
float Cn = 0;
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Accelerometer Functions">

/*
  Read register content into buffer.
The default count is 1 byte.

The buffer needs to be pre-allocated
if count > 1
*/
void regRead(byte reg, byte *buf, byte count = 1) {
  I2c.write(I2C_ADDR, reg);
  I2c.read(I2C_ADDR, reg, count);

  for (int i = 0; i < count; i++)
    *(buf + i) = I2c.receive();
}

/*
  Write a byte value into a register
*/
void regWrite(byte reg, byte val) {
  I2c.write(I2C_ADDR, reg, val);
}

/*
  Put MMA8453Q into standby mode
*/
void standbyMode() {
  byte reg;
  byte activeMask = 0x01;

  regRead(REG_CTRL_REG1, &reg);
  regWrite(REG_CTRL_REG1, reg & ~activeMask);
}

/*
Put MMA8453Q into active mode
*/
void activeMode() {
  byte reg;
  byte activeMask = 0x01;

  regRead(REG_CTRL_REG1, &reg);
  regWrite(REG_CTRL_REG1, reg | activeMask);
}

/*
  Use fast mode (low resolution mode)
The acceleration readings will be
limited to 8 bits in this mode.   
*/
void lowResMode() {
  byte reg;
  byte fastModeMask = 0x02;

  regRead(REG_CTRL_REG1, &reg);
  regWrite(REG_CTRL_REG1, reg | fastModeMask);
}

/*
  Use default mode (high resolution mode)
The acceleration readings will be
10 bits in this mode.   
*/
void hiResMode() {
  byte reg;
  byte fastModeMask = 0x02;

  regRead(REG_CTRL_REG1, &reg);
  regWrite(REG_CTRL_REG1, reg & ~fastModeMask);
}

/*
  get accelerometer readings (x, y, z)
by default, standard 10 bits mode is used.

if accelerometer is initialized to use low res mode,
isHighRes must be passed in as false.
*/
void getAccXYZ(int *x, int *y, int *z, bool isHighRes = true) {
  byte buf[6];

  if (isHighRes) {
    regRead(REG_OUT_X_MSB, buf, 6);
    *x = buf[0] << 2 | buf[1] >> 6 & 0x3;
    *y = buf[2] << 2 | buf[3] >> 6 & 0x3;
    *z = buf[4] << 2 | buf[5] >> 6 & 0x3;
  }
  else {
    regRead(REG_OUT_X_MSB, buf, 3);
    *x = buf[0] << 2;
    *y = buf[1] << 2;
    *z = buf[2] << 2;
  }

  if (*x > 511) *x = *x - 1024;
  if (*y > 511) *y = *y - 1024;
  if (*z > 511) *z = *z - 1024;
}

//</editor-fold>

// <editor-fold defaultstate="collapsed" desc="Calibrate Gyro">

float CalGyro() {
  float val = 0.0;
  digitalWrite(PIN_MODE_LED, HIGH);
  delay(500);
  for (int i = 0; i < 25; i++) {
    val += analogRead(PIN_GYRO_X);
    delay(10);
  }

  val /= 25.0;

  Serial.print("GyroX Stationary=");
  Serial.println(val);
  digitalWrite(PIN_MODE_LED, LOW);

  return val;
}// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Angle estimation">
float GetAvgAngle() {
  int count = 0;
  float a = 0;

  for (int i = 0; i < ANGLE_BUFFER_LENGTH; i++) {
    if (angleBuffer != 0) {
      count++;
      a += angleBuffer;
    }
  }

  if (count > 0)
    return a / float(count);
  else
    return 0.0;
}

float GetAccAngle() {
  getAccXYZ(&VxAcc, &VzAcc, &VyAcc);

  float r = sqrt((float) VzAcc * (float) VzAcc + (float) VyAcc * (float) VyAcc);
  accAngle = (float) VzAcc / r; //approximates sine

  return accAngle;
}

float EstimateAngle() {
  currTimeStamp = micros();
  elapsedTime = currTimeStamp - prevTimeStamp;
  prevTimeStamp = currTimeStamp;

  elapsedTimeSec = (float) elapsedTime / 1e6f;

  float angle = GetAccAngle();
  if (isFirstTime) {
    currAngle = angle;
    isFirstTime = false;
  }
  else {
    VxGyro = analogRead(PIN_GYRO_X);
    degX = (float) (VxGyro - GYRO_X_INIT_VAL) * 3300.0f / 512.0f / 180.0f * (float) elapsedTimeSec;
    currAngle = 0.95 * (prevAngle + degX) + 0.05 * angle;
  }

  prevAngle = currAngle;

  if (MotorOff) { //for debugging purposes
    Serial.print("\tcurrAngleAvg=");
    Serial.print(GetAvgAngle(), 4);
    Serial.print("\tcurrAngle=");
    Serial.print(currAngle, 4);
    Serial.print("\taccAngle=");
    Serial.print(accAngle);
    Serial.print("\tgyroAngle=");
    Serial.print(degX);
    Serial.print("\tVxGyro=");
    Serial.print(VxGyro);
    Serial.print("\telapsedTime=");
    Serial.print(elapsedTime);
    Serial.print("\tthrottle=");
    Serial.println(throttle);
  }

  return currAngle;
}
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="Drive">
void MoveWheels(WheelDirection dir, int speed) {
  if (MotorOff) return;

  if (speed > 255) speed = 255;
  else if (speed < 0) speed = 0;

  if (dir == DIR_STOP) {
    digitalWrite(PIN_MOTOR_1, LOW);
    digitalWrite(PIN_MOTOR_2, LOW);
  }
  else if (dir == DIR_FORWARD) {
    digitalWrite(PIN_MOTOR_2, LOW);
    analogWrite(PIN_MOTOR_1, speed);
  }
  else if (dir == DIR_BACKWARD) {
    digitalWrite(PIN_MOTOR_1, LOW);
    analogWrite(PIN_MOTOR_2, speed);
  }
}
// </editor-fold>

void setup() {
  I2c.begin();
  Serial.begin(9600);

  standbyMode(); //register settings must be made in standby mode
  regWrite(REG_XYZ_DATA_CFG, FULL_SCALE_RANGE_2g);
  hiResMode();
  activeMode();

  pinMode(PIN_MOTOR_1, OUTPUT);
  pinMode(PIN_MOTOR_2, OUTPUT);

  digitalWrite(PIN_MOTOR_1, LOW);
  digitalWrite(PIN_MOTOR_2, LOW);

  pinMode(PIN_MODE_LED, OUTPUT);

  pinMode(PIN_MODE_SWITCH, INPUT);
  digitalWrite(PIN_MODE_SWITCH, HIGH);

  Serial.print("Motor is ");
  if (digitalRead(PIN_MODE_SWITCH) == HIGH) {
    MotorOff = true;
    Serial.println("OFF");
  }
  else {
    MotorOff = false;
    Serial.println("ON");
  }

  byte b;
  regRead(REG_WHO_AM_I, &b);
  Serial.println(b, HEX);

  for (int i = 0; i < ANGLE_BUFFER_LENGTH; i++) angleBuffer = 0;

  GYRO_X_INIT_VAL = CalGyro();
}

void loop() {
  float a = EstimateAngle() - INIT_ANGLE;

  angleBuffer[angleBufferIndex] = a;
  angleBufferIndex = (angleBufferIndex + 1) % ANGLE_BUFFER_LENGTH;
  float ang = GetAvgAngle();

  curErr = ang - INIT_ANGLE; //error   
  SumErr += curErr;

  if (SumErr > SumErrMax) SumErr = SumErrMax;
  else if (SumErr < SumErrMin) SumErr = SumErrMin;

  //Ki*SumE/(Kp*Fs*X)
  integralTerm = SumErr * elapsedTimeSec * Ki / Kp * 10.0;
  derivativeTerm = curErr - prevErr;

  if(derivativeTerm > 0.1) derivativeTerm = 0.1;
  else if (derivativeTerm < -0.1) derivativeTerm = -0.1;

  // Kd(curErr-prevErr)*Ts/(Kp*X)
  derivativeTerm = derivativeTerm * Kd * elapsedTimeSec / Kp;

  if(derivativeTerm > 120) derivativeTerm = 120;
  else if (derivativeTerm < -120) derivativeTerm = -120;

  Cn = (curErr + integralTerm + derivativeTerm) * Kp / 10.0;
  Serial.println(Cn);
  WheelDirection dir;

  if (Cn > 0) dir = DIR_FORWARD;
  else if (Cn < -0) dir = DIR_BACKWARD;
  else dir = DIR_STOP;

  throttle = abs(Cn);

  if (abs(ang) > 0.7)  MoveWheels(DIR_STOP, 0); //if angle too large to correct, stop motor        
  else MoveWheels(dir, throttle);

  prevErr = curErr;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-12-14 19:22:17 | 显示全部楼层
没人能回答一下吗

出0入25汤圆

发表于 2013-12-14 20:14:34 | 显示全部楼层
enum 变量定义不对!

出0入0汤圆

 楼主| 发表于 2013-12-14 20:33:37 | 显示全部楼层
为何不对

出0入0汤圆

 楼主| 发表于 2013-12-14 20:37:29 | 显示全部楼层
墨非 发表于 2013-12-14 20:14
enum 变量定义不对!

哪里不对?这个程序在他人的机子上编译通过的。

出0入25汤圆

发表于 2013-12-14 20:42:25 | 显示全部楼层
typedef  enum  VALUE
{
one,
two,
three,
}value_t;

enum VALUE num;
value_t num;

出0入0汤圆

 楼主| 发表于 2013-12-14 22:59:00 | 显示全部楼层
墨非 发表于 2013-12-14 20:42
typedef  enum  VALUE
{
one,

谢谢回复,我再试试看

出0入0汤圆

发表于 2013-12-20 23:13:04 | 显示全部楼层
你好,你的328P熔丝位设置的是多少呢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 23:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表