Go Down

Topic: To many changes in the servo makes processor stop [HELP] (Read 825 times) previous topic - next topic

freak174

Hello arduino community :)

Does any one out there know why the arduino processor stops (freezes) when I give it to many values. Let me demonstrate with an example.

Lets say I have a button, it gives either +90 degrees or -90 degrees. So if I press once, it ill rotate +90 degrees, if I press it once again it will go -90 degrees.

If I let the servo go fully 90 degrees, and then push the button again, it will rotate back 90 degrees. As it should do.
BUT if I press it a couple of times before it has reached it locations, the arduino freezes and you will have to wait for like 10 seconds until the arduino responds again.

Ive tried both delays and millis.

Conclusions?

Cheers!

Edit:
I just gave it another shot and also notified that it also freezes even if you let it rotate 90 degrees and immediatly pushes the button again.

DuaneB

How are you powering the servo, check the two links in my signature to see why this maters

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

freak174

Hello DuaneB!
Yupp, I had another thread in the sensor forum. And Im still continuing with your advice, using an external power supply for the servo :)

zoomkat

Quote
Conclusions?


i conclude you should post your code if you want to consider the posibility you have bad code.  :)
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

freak174


Quote
Conclusions?


i conclude you should post your code if you want to consider the posibility you have bad code.  :)


Ofcourse!

This isnt really a pushbutton, but I thought it would be more easy to explain in those terms.
It is a sensor, that outputs the inclination of the board (in degrees). The servos are controlled by an intervall of the degree values.
Code: [Select]
#include <Servo.h>
#include <Wire.h>
#include "Kalman.h"
#define LED_PIN 13

Servo YawServo;
long lastPulsing;
bool blinkState = false;



Kalman kalmanX;
Kalman kalmanY;

uint8_t IMUAddress = 0x68;

/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;

double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;

uint32_t timer;

void setup() { 
  Serial.begin(115200);
  YawServo.attach(9);

  // configure LED for output
  pinMode(LED_PIN, OUTPUT);
 
  Wire.begin(); 
  i2cWrite(0x6B,0x00); // Disable sleep mode 
  if(i2cRead(0x75,1)[0] != 0x68) { // Read "WHO_AM_I" register
    Serial.print(F("MPU-6050 with address 0x"));
    Serial.print(IMUAddress,HEX);
    Serial.println(F(" is not connected"));
    while(1);
  }     
 
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();
  lastPulsing = millis() + 20;
}

void loop() {
  /* Update all the values */
  uint8_t* data = i2cRead(0x3B,14); 
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]); 
  tempRaw = ((data[6] << 8) | data[7]); 
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
 
  /* Calculate the angls based on the different sensors and algorithm */
  accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;   
 
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle += gyroXrate*((double)(micros()-timer)/1000000); // Calculate gyro angle without any filter 
  gyroYangle += gyroYrate*((double)(micros()-timer)/1000000);
  //gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  //gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
 
  compAngleX = (0.93*(compAngleX+(gyroXrate*(double)(micros()-timer)/1000000)))+(0.07*accXangle); // Calculate the angle using a Complimentary filter
  compAngleY = (0.93*(compAngleY+(gyroYrate*(double)(micros()-timer)/1000000)))+(0.07*accYangle); 
 
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();
 
  temp = ((double)tempRaw + 12412.0) / 340.0;

 
  Serial.print(kalAngleX);Serial.print("\t");
  Serial.print(kalAngleY);Serial.print("\t");
 
    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
   
   //SERVO 
   if(millis() >= lastPulsing + 20) {     
     if((180-kalAngleX) > 8){
       YawServo.write(180);
     }
     else if((180-kalAngleX) < 4){
       YawServo.write(0);
   }
   lastPulsing = millis();

}
   
  Serial.print("\n");
 
  delay(1); // The accelerometer's maximum samples rate is 1kHz
}


void i2cWrite(uint8_t registerAddress, uint8_t data){
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
  uint8_t data[nbytes]; 
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i++)
    data[i] = Wire.read();
  return data;
 

}

Go Up