使用Arduino时,LIS3DH加速度计输出空值

时间:2018-04-23 20:58:32

标签: c++ arduino adafruit

我正在使用带有Adafruit电机护罩(v2)的Arduino Uno来为电机和LIS3DH加速度计供电和控制。使用更简单的代码,其中电机正向前进一定数量的脉冲(由编码器输出),加速度计的相同功能输出正确的值。代码如下所示。

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_Sensor.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#define pi 3.14159
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
float distance = 30;

Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
unsigned int pulsesperturn = 56 * 64 / 2 ;
float circumference = 5.25 * 3.14159;
int pulses;
//int count = 0;

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif

void setup(void) {
#ifndef ESP8266
  while (!Serial);     // will pause Zero, Leonardo, etc until serial console opens
#endif

  Serial.begin(9600);
  AFMS.begin();

  Serial.println("LIS3DH test!");
  if (! lis.begin(0x19)) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("LIS3DH found!");
  lis.setRange(LIS3DH_RANGE_4_G);   // 2, 4, 8 or 16 G!
  //

}

void loop() {

  //  //  }
  //  myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
  //  myMotor->run(FORWARD);
  //  delay(2500);
  //  myMotor->setSpeed(0);
  //  //  right = 0;
  //  delay(1000);
  //  //  right = 1;
  //  myMotor->run(BACKWARD);
  //  myMotor->setSpeed(255);
  //  delay(2500);
  //  myMotor->setSpeed(0);
  //  //  right = 0;
  //  delay(1000);
  //  //  right = 1;
  myMotor->run(FORWARD);
  myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes

  if (pulsesperturn  <= pulses ) {
    myMotor->run(RELEASE);
    myMotor->run(RELEASE);
    myMotor->setSpeed(0);
    stoppedAccel();
    pulses = 0;
  }

  // Then print out the raw data
  //  Serial.print("X:  "); Serial.print(lis.x);
  //  Serial.print("  \tY:  "); Serial.print(lis.y);
  //  Serial.print("  \tZ:  "); Serial.print(lis.z);

  //  for (int a = 1; a < 20; a = a + 1) {

  //  lis.read();      // get X Y and Z data at once
  //  sensors_event_t event;
  //  lis.getEvent(&event);
  //
  //  /* Display the results (acceleration is measured in m/s^2) */
  //  //      Serial.print("  \tAngle:  "); Serial.print(angle);
  //  //
  //  //  Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
  //  Serial.print(" \tY: "); Serial.print(event.acceleration.y);
  //  Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
  //  //      Serial.println(" m/s^2 ");
  //
  //  Serial.println();
  //  //
  //  //  char buffer[5];
  //  //  Serial.print("#S|WRITEDATA|[");
  //  //  Serial.print(angle); // accels
  //  //  Serial.println("]#");
  //
  //  //  WriteAccel();
  //  delay(10);
  //  }
  //  myMotor->run(FORWARD);


  //
  //  myMotor->run(RELEASE);
  //  myMotor->setSpeed(255);
  //  if (distance / circumference * pulsesperturn <= pulses) {
  //    myMotor->setSpeed(0);
  //    delay(2500);
  //  }
  //  myMotor->setSpeed(255);
  //  myMotor->run(FORWARD);
  //  pulses = 0;

  Serial.print("pulses = ");
  Serial.println(pulses);

  attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
  /* Or....get a new sensor event, normalized */


}

void counter()
{
  pulses++;
}

void stoppedAccel()
{
  for (int a = 1; a < 150; a = a + 1) {
    lis.read();      // get X Y and Z data at once
    sensors_event_t event;
    lis.getEvent(&event);
    float angle = asin(event.acceleration.z / 9.81) * 180  / pi  ;

    Serial.print("  \tAngle:  "); Serial.print(angle);
    //
    //  Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
    //    Serial.print(" \tY: "); Serial.print(event.acceleration.y);
    //    Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
    //      Serial.println(" m/s^2 ");

    Serial.println();

    //
    //  char buffer[5];
    //  Serial.print("#S|WRITEDATA|[");
    //  Serial.print(angle); // accels
    //  Serial.println("]#");
    delay(10);
  }
}

在此代码中,将电机向前运行一段距离6次,然后将其向后运行相同的距离,电机正常运行,加速度计表示已找到它,但它仅输出空值。

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159

//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;


#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif



void setup(void)
{
#ifndef ESP8266
  while (!Serial);     // will pause Zero, Leonardo, etc until serial console opens
#endif


  Serial.begin(9600);
  AFMS.begin();
  Serial.println("LIS3DH test!");
  if (! lis.begin(0x19)) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("LIS3DH found!");
  lis.setRange(LIS3DH_RANGE_4_G);   // 2, 4, 8 or 16 G!


  //  myMotor->run(FORWARD);
  myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}

void loop() {
  motorDirection();
}

void counter()
{
  pulses++;
}

void bcounter()
{
  b++;
}

void motorDirection()
{
  while (b < 6) {
    myMotor->run(FORWARD);
    readInt();
    if (500 * conversion <= pulses) {
      myMotor->run(RELEASE);
      myMotor->run(RELEASE);
      pulses = 0;
      bcounter();
      if (b == 6) {
        stoppedAccel();
      }
      delay(1500);
    }
    //      break;

  }

  while (b == 6) {

    myMotor->run(BACKWARD);
    readInt();
    if (500 * b <= pulses) {
      myMotor->run(RELEASE);
      myMotor->run(RELEASE);
      bcounter();
      stoppedAccel();
      pulses = 0;
      delay(500);
      break;
    }
  }
  while (b > 6) {
    b = 0;
    break;
  }

}

// 169 forward per 1000, 171 backward

void stoppedAccel()
{
  for (int a = 1; a < 150; a = a + 1) {
    lis.read();      // get X Y and Z data at once
    sensors_event_t event;
    lis.getEvent(&event);
    float angle = asin(event.acceleration.z / 9.81) * 180  / pi  ;

    Serial.print("  \tAngle:  "); Serial.print(angle);
    //
    //  Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
    //    Serial.print(" \tY: "); Serial.print(event.acceleration.y);
    //    Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
    //      Serial.println(" m/s^2 ");

    Serial.println();

    //
    //  char buffer[5];
    //  Serial.print("#S|WRITEDATA|[");
    //  Serial.print(angle); // accels
    //  Serial.println("]#");
    delay(100);
  }
}

void readInt()
{
  attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
  Serial.print("pulses = ");
  Serial.println(pulses);
}

我尝试了各种各样的东西但是我没有CS的背景,特别是在C ++中,所以我的尝试并没有多少成果。任何建议都会有所帮助。

1 个答案:

答案 0 :(得分:0)

问题是使用延迟()。硬件是如何工作的,我不确定,但我相信以这种方式阻止它会抛弃硬件,使其输出为空。以下是使用millis()的更正代码。

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
float angle;
const long interval = 1000;
unsigned long previousMillis;


//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;


#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif



void setup(void)
{
#ifndef ESP8266
  while (!Serial);     // will pause Zero, Leonardo, etc until serial console opens
#endif


  Serial.begin(9600);
  AFMS.begin();
  Serial.println("LIS3DH test!");
  if (! lis.begin(0x19)) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("LIS3DH found!");
  lis.setRange(LIS3DH_RANGE_4_G);   // 2, 4, 8 or 16 G!


  //  myMotor->run(FORWARD);
  myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}

void loop() {
  motorDirection();
  //    stoppedAccel();
}

void counter()
{
  pulses++;
}

void bcounter()
{
  b++;
}

void motorDirection()
{
  //serial.write
  while (b < 6) {
    myMotor->run(FORWARD);
    readInt();
    if (500 * conversion <= pulses) {
      myMotor->run(RELEASE);
      bcounter();
      previousMillis = millis();
      timing();
      //      previousMillis = currentMillis;

      pulses = 0;

      if (b == 6) {
        stoppedAccel();
      }
    }
    break;

  }

  while (b == 6) {
    myMotor->run(BACKWARD);
    readInt();
    if (500 * b <= pulses) {
      myMotor->run(RELEASE);
      pulses = 0;
      bcounter();
      stoppedAccel();

      break;
    }
  }
  while (b > 6) {
    b = 0;
    break;
  }

}

// 169 forward per 1000, 171 backward

void stoppedAccel()
{
  for (int a = 1; a < 200; a = a + 1) {
    lis.read();      // get X Y and Z data at once
    sensors_event_t event;
    lis.getEvent(&event);
    angle = asin(event.acceleration.z / 9.81) * 180  / pi  ;

    Serial.print("  \tAngle:  "); Serial.print(angle);
    //
    //  Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
    //    Serial.print(" \tY: "); Serial.print(event.acceleration.y);
    //    Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
    //      Serial.println(" m/s^2 ");
    Serial.println();
    //
    //  char buffer[5];
    //  Serial.print("#S|WRITEDATA|[");
    //  Serial.print(angle); // accels
    //  Serial.println("]#");
    delay(10);
  }
}

void readInt()
{
  attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
  Serial.print("pulses = ");
  Serial.println(pulses);
}

void timing()
{
  while (millis() - previousMillis <= interval) {
    myMotor->run(RELEASE);
  }
}