【问题标题】:How to code EEPROM with potentiometer in Arduino如何在 Arduino 中使用电位器对 EEPROM 进行编码
【发布时间】:2018-01-26 04:21:49
【问题描述】:

我有一个从网站获得的代码。我一直在尝试在该代码中添加 EEPROM,但我做错了。我尝试添加 EEPROM.write 和 EEPROm.read 我还添加了另一个伺服

谁能帮帮我,在代码中添加 EEPROM? 提前谢谢你 :)

代码如下(带播放和录音功能的简单机械臂):

#include <Servo.h>
#include <EEPROM.h>

const int PinButton1 = 2;  // pin 2   
const int PinButton2 = 3;  // pin 3
int mode = 1;     // case 1 program robot arm. case 2 replay positions 
int bounce = 0;
volatile int buttonPress = 0;
unsigned long lastButtonPressTime = 0;
volatile unsigned long bounceTime = 0;
Servo Arm0Servo;      //servo objects
Servo Arm1Servo;      // Ihave renumbered servos 26 1 2017
Servo Arm2Servo;
Servo Arm3Servo;
Servo Arm4Servo;
int pos1,pos2,pos3,pos4,pos0;
int PosArm[5] ;       // array 
int ArmPos[100][5];   // array to hold arm positions up to 100
int PosCount = 0;     //  to count number of positions increased when button     pressed
int PosCountMax = 0;  //  number of positions recorded when double button push initiates replay mode
int PosReached = 0;   // used to check that arm has moved from one recorded position to next position
int addr = 0;
boolean recorded = false;

void setup() {  
     for(int i = 0; i <100 ; i++ ){
     for(int p = 0; p <5 ; p++ ){
         ArmPos[i][p] = -1;
     }
 }
pinMode(PinButton1 , OUTPUT);
digitalWrite(PinButton1 ,LOW);
pinMode(PinButton2, INPUT_PULLUP);
//  I have made a small change here due to problem using some Arduinos
//attachInterrupt( digitalPinToInterrupt(PinButton2),ButtonPress , LOW );
// digitalPinToInterrupt(PinButton2) may not be defined!
attachInterrupt( 1,ButtonPress , LOW );   // interupt to capture button presses

// attach servos to relervent pins on arduino nano
Arm0Servo.attach(12); // grip    90 to 180 open    limits of servo movement
Arm1Servo.attach(11); // elbow      to 130 up
Arm2Servo.attach(10); // shoulder   10 to 50 down
Arm3Servo.attach(9);  // turn    0  to 180 right 
Arm4Servo.attach(8);  // turn    0  to 180 right
}

void loop() {
  switch(mode){
    case 1 :  //  program robot arm. 1 press to remember position. 2 presses to progress next case 2 replay mode
              // analogRead(pin) that reads poteniometers on training arm
    PosArm[0] = map(analogRead(0),480,1024,180,10); // map (480,1024 value from potentiometer to 180,90 value sent to servo)
    EEPROM.write(addr, PosArm[0]);
    addr++;
    PosArm[1] = map(analogRead(1),480,1024,180,10);
    EEPROM.write(addr, PosArm[1]);
    addr++;
    PosArm[2] = map(analogRead(2),480,1024,180,10);
    EEPROM.write(addr, PosArm[2]);
    addr++;
    PosArm[3] = map(analogRead(3),480,1024,180,10);
    EEPROM.write(addr, PosArm[3]);
    addr++;
    PosArm[4] = map(analogRead(4),480,1024,180,10);
    EEPROM.write(addr, PosArm[4]);
             addr++;
    MoveArm();                          // call method  
    if(buttonPress == 1){               // flag set by interupt when button is pressed          
         buttonPress = 0;               // reset flag 
         if( millis() > (lastButtonPressTime + 1000)){    // only one button press in one secound
             // record  position of arm PosArm to array[100][] of armpositions        
             ArmPos[PosCount][0] = PosArm[0];

             ArmPos[PosCount][1] = PosArm[1];

             ArmPos[PosCount][2] = PosArm[2];

             ArmPos[PosCount][3] = PosArm[3];

             ArmPos[PosCount][4] = PosArm[4];


             if (addr == 512) {
               EEPROM.write(addr, 255);
               break;
             }

             if( PosCount < 100) {      // stop recording if over 100 positions recorded (memory limitations)
                 PosCount++;         
             }
         }else{                         //  more than one button press
             mode = 2;                  // go to next phase
             PosCountMax  = PosCount;   // set number of arm positions recorded
             PosCount = 0;              // reset count ready to read  arm position array from begining 
         }
    lastButtonPressTime = millis();              
    }
  break;
case 2 :        // read arm position array
    PosReached = 0;
    for(int i = 0; i <5 ; i++ ){   //adjust servo positions   
        // we move the servos in small steps and the delay(20)  makes arm motion smooth and slow
        if( PosArm[i] > ArmPos[PosCount][i]) PosArm[i] = PosArm[i] - 1;  // if actual position is greater than requird position reduce position by 1
        if( PosArm[i] < ArmPos[PosCount][i]) PosArm[i] = PosArm[i] + 1;  // if actual position is less than required position value increase position valuue by 1
        if( PosArm[i] == ArmPos[PosCount][i]) PosReached++;              // check if servo  has reached required position/angle
    }

    if(PosReached == 5) PosCount++;        // if all 4 servos have reached position  then increase array index (PosCount)to next position in array
    if(PosCount == PosCountMax) PosCount = 0;   //  if end of array reached reset index to 0 and repeat.
    Play();   // physically move arm to updated position, this is broken into small steps
    delay(5);   // pause between moves so over all motion is slowed down
  break;
default :
  break;
  }    
}

void MoveArm() {   // write arm position data to servos
  for (int i = 0 ; i < 5 ; i++) {
  if (PosArm[i] < 5) PosArm[i] = 5;  // limit servo movement to prevent hitting end stops
  if (PosArm[i] > 175) PosArm[i] = 175;  // servo.write limited 5 - 175  
  }
  Arm0Servo.write(PosArm[0]);
  Arm1Servo.write(PosArm[1]);
  Arm2Servo.write(PosArm[2]);
  Arm3Servo.write(PosArm[3]);
  Arm4Servo.write(PosArm[4]);
  Play();
  delay(5);
}
void Play() {   // write arm position data to servos
  for (int i = 0 ; i < 5 ; i++) {
  if (PosArm[i] < 5) PosArm[i] = 5;  // limit servo movement to prevent hitting end stops
  if (PosArm[i] > 175) PosArm[i] = 175;  // servo.write limited 5 - 175  
  }

  if (addr == 0) {
  PosArm[0] = EEPROM.read(addr);
  pos0 = EEPROM.read(addr+5);
  addr++;

  PosArm[1] = EEPROM.read(addr);
  pos1 = EEPROM.read(addr+5);
  addr++;

  PosArm[2] = EEPROM.read(addr);
  pos2 = EEPROM.read(addr+5);
  addr++;

  PosArm[3] = EEPROM.read(addr);
  pos3 = EEPROM.read(addr+5);
  addr++;

  PosArm[4] = EEPROM.read(addr);
  pos4 = EEPROM.read(addr+5);
  addr++;

  }

  }
   void ButtonPress(){   //  interupt to capture button press
   if(micros() > (bounceTime + 3000)){ // debounce timer 
    bounceTime = micros();          // ingnore interupts due to button bounce
    buttonPress = 1;     // flag for button pressed
}

}

【问题讨论】:

  • “添加 EEPROM”是什么意思?您的程序可以对其进行写入和/或读取,您想做什么以及到目前为止您尝试了什么?
  • 程序运行良好,可以读写,但我想将写入的数据永久保存在 EEPROM 中。我试过 EEPROM。 write 和 EEPROM.read,它仍然可以工作,但它不能再读取写入数据。谢谢你:)
  • 那么你的代码在哪里呢?
  • 我将编辑上面发布的代码。
  • 请减少您的代码示例!这不是您工作的审查中心!如果您遇到写入 eeprom 之类的问题,请将您的代码精确地缩减到那个程度!

标签: c++ arduino robotics eeprom servo


【解决方案1】:

由于以下问题,您发布的代码将永远不会尝试从 EEPROM 读取数据:

当您的微控制器启动时,变量mode 设置为1。如果您仔细查看loop 函数,您会发现您的代码将至少进入一次case 1 分支,它基本上是在其中写入数据到 EEPROM 并且 - 更重要的是 - 由于 addr++ 指令,会将 addr 设置为 0 以外的值(除非您运行代码太久以至于遇到整数溢出)。

您尝试从 EEPROM 读取的唯一位置是 Play 函数。由于此函数中的if (addr == 0) 条件,您将永远不会执行EEPROM.read 指令,因为addr 不会为0,如上所述。

【讨论】:

  • 约翰内斯是对的。此外,除非它进入模式 2 或 3,否则该草图将每秒写入 EEPROM 1000 次以上。这将使您的 EEPROM 的寿命不到 2 小时,以达到 100000 的电池周期,因为 ATMEL 是寿命。所以你真的想重做你对 EEPROM 的处理。你的 Arduino 可能已经有一个死掉的 EEPROM。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多