ostrich12 发表于 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) are 8 MSBs of 10-bit sample
const byte REG_OUT_X_LSB = 0x02; //(R) are 2 LSBs of 10-bit sample
const byte REG_OUT_Y_MSB = 0x03; //(R) are 8 MSBs of 10-bit sample
const byte REG_OUT_Y_LSB = 0x04; //(R) are 2 LSBs of 10-bit sample
const byte REG_OUT_Z_MSB = 0x05; //(R) are 8 MSBs of 10-bit sample
const byte REG_OUT_Z_LSB = 0x06; //(R) 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;
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;

if (isHighRes) {
    regRead(REG_OUT_X_MSB, buf, 6);
    *x = buf << 2 | buf >> 6 & 0x3;
    *y = buf << 2 | buf >> 6 & 0x3;
    *z = buf << 2 | buf >> 6 & 0x3;
}
else {
    regRead(REG_OUT_X_MSB, buf, 3);
    *x = buf << 2;
    *y = buf << 2;
    *z = buf << 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 = 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;
}

ostrich12 发表于 2013-12-14 19:22:17

没人能回答一下吗

墨非 发表于 2013-12-14 20:14:34

enum 变量定义不对!

ostrich12 发表于 2013-12-14 20:33:37

为何不对

ostrich12 发表于 2013-12-14 20:37:29

墨非 发表于 2013-12-14 20:14
enum 变量定义不对!

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

墨非 发表于 2013-12-14 20:42:25

typedefenumVALUE
{
one,
two,
three,
}value_t;

enum VALUE num;
value_t num;

ostrich12 发表于 2013-12-14 22:59:00

墨非 发表于 2013-12-14 20:42
typedefenumVALUE
{
one,


谢谢回复,我再试试看

wangli08324 发表于 2013-12-20 23:13:04

你好,你的328P熔丝位设置的是多少呢
页: [1]
查看完整版本: 请帮忙看一下这个程序报错的问题,急!