ADXL345 выдает ошибку проводки в режиме SPI

Я получаю следующий вывод от последовательного монитора при попытке использовать ADXL345 с Arduino Uno в режиме SPI (режим I2C работает нормально):

CA
Ooops, no ADXL345 detected ... Check your wiring!

См. фотографии проводки. Я попробовал это с другой прорывной платой, и это дает те же результаты. Интересно, что в этом руководстве говорится, что прорыв должен работать в режиме SPI, но это проиллюстрировано только для I2C. https://learn.adafruit.com/adxl345-digital-accelerometer?view= all#assembly-and-wiring

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>    
/* Одновременно присваиваем этому датчику уникальный идентификатор */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(13,12,11,9);
//Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();

//Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(clock,miso,mosi,cs,sensorID);
void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2"); 
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    ");

  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 ");
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 ");
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 ");
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 ");
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 ");
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 ");
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 ");
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 ");
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 ");
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 ");
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 ");
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 ");
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 ");
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 ");
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 ");
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 ");
      break;
    default:
      Serial.print  ("???? ");
      break;
  } 
  Serial.println(" Hz"); 
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- ");

  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 ");
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 ");
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 ");
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 ");
      break;
    default:
      Serial.print  ("?? ");
      break;
  } 
  Serial.println(" g"); 
}

void setup(void)
{
#ifndef ESP8266
  while (!Serial); // для Леонардо/Микро/Зеро
#endif
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");
  pinMode(9,OUTPUT);
  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);

  /* Display some basic information on this sensor */
  displaySensorDetails();

  /* Display additional settings (outside the scope of sensor_t) */
  displayDataRate();
  displayRange();
  Serial.println("");
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  accel.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
// delay(500);
}

, 👍0


1 ответ


Лучший ответ:

0

Я заставил его работать, используя библиотеку Sparkfun вместо библиотеки Adafruit, и вставив пару операторов delay(100) в настройку (без них вывод постоянно был -13365, -13365, -13365). Я до сих пор не совсем понимаю, зачем вообще нужны операторы задержки.

/* ************************************************* ***
* SparkFun_ADXL345_Пример
* Трехосевой акселерометр Breakout - ADXL345
* Пример руководства по подключению
*
* Использование библиотеки Sparkfun ADXL345.
* Исходный файл Bildr ADXL345 изменен для поддержки
* связь I2C и SPI
*
* Э. Роберт @ SparkFun Electronics
* Создано: 13 июля 2016 г.
* Обновлено: 6 сентября 2016 г.
*
* Особенности среды разработки:
* Ардуино 1.6.11
*
* Технические характеристики оборудования:
* СпаркФун ADXL345
* Ардуино Уно
* *************************************************/

#include <SparkFun_ADXL345.h>         // Библиотека SparkFun ADXL345

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
ADXL345 adxl = ADXL345(9);           // ИСПОЛЬЗОВАТЬ ДЛЯ СВЯЗИ SPI, ADXL345(CS_PIN);
//ADXL345 adxl = ADXL345(); // ИСПОЛЬЗОВАТЬ ДЛЯ СВЯЗИ I2C

/****************** INTERRUPT ******************/
/*      Uncomment If Attaching Interrupt       */
//целое прерываниеPin = 2; // Настройте контакт 2 как контакт прерывания (для большинства плат Arduino)


/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

  Serial.begin(9600);                 // Запускаем последовательный терминал
  Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
  Serial.println();

  adxl.powerOn();                     // Включаем ADXL345
  delay(100); 
  adxl.setRangeSetting(16);           // Задаем настройки диапазона
                                      // Допустимые значения: 2 г, 4 г, 8 г или 16 г
                                      // Более высокие значения = более широкий диапазон измерений
                                      // Более низкие значения = большая чувствительность
  delay(100); 
  adxl.setSpiBit(0);                  // Настройте устройство в 4-проводном режиме SPI, если установлено значение «0», или в 3-проводном режиме SPI, если установлено значение 1.
                                      // По умолчанию: установлено на 1
                                      // Выводы SPI на ATMega328: 11, 12 и 13 в качестве ссылки в библиотеке SPI
  delay(100); 
// Установить режим SPI на соответствующий ADXL345 (думаю, он будет здесь по умолчанию?)

  adxl.setActivityXYZ(1, 0, 0);       // Установите для активации обнаружения движения по осям "adxl.setActivityXYZ(X, Y, Z);" (1 == ВКЛ, 0 == ВЫКЛ)
  adxl.setActivityThreshold(75);      // 62,5 мг на шаг // Установить активность // Пороги бездействия (0-255)

  adxl.setInactivityXYZ(1, 0, 0);     // Установите для обнаружения бездействия по всем осям "adxl.setInactivityXYZ(X, Y, Z);" (1 == ВКЛ, 0 == ВЫКЛ)
  adxl.setInactivityThreshold(75);    // 62,5 мг на шаг // Установка бездействия // Пороги бездействия (0-255)
  adxl.setTimeInactivity(10);         // Сколько секунд бездействия неактивно?

  adxl.setTapDetectionOnXYZ(0, 0, 1); // Обнаружение касаний в направлениях, включенных "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ВКЛ, 0 == ВЫКЛ)

  // Установите значения для того, что считается TAP и что такое DOUBLE TAP (0-255)
  adxl.setTapThreshold(50);           // 62,5 мг на шаг
  adxl.setTapDuration(15);            // 625 мкс на приращение
  adxl.setDoubleTapLatency(80);       // 1,25 мс на шаг
  adxl.setDoubleTapWindow(200);       // 1,25 мс на шаг

  // Установите значения для того, что считается СВОБОДНЫМ ПАДЕНИЕМ (0-255)
  adxl.setFreeFallThreshold(7);       // (5–9) рекомендуется — 62,5 мг за шаг
  adxl.setFreeFallDuration(30);       // (20 - 70) рекомендуется - 5 мс на приращение

  // установка всех прерываний на вывод INT1
  //adxl.setImportantInterruptMapping(1, 1, 1, 1, 1); // Устанавливает "adxl.setEveryInterruptMapping(одиночное нажатие, двойное нажатие, свободное падение, активность, бездействие);"
                                                        // Принимает только 1 или 2 значения для контактов INT1 и INT2. При этом выбирается контакт ADXL345, который будет использоваться для прерываний.
                                                        // У этой библиотеки могут быть проблемы с использованием контакта INT2. По умолчанию используется контакт INT1.

  // Включаем прерывания для каждого режима (1 == ON, 0 == OFF)
  adxl.InactivityINT(1);
  adxl.ActivityINT(1);
  adxl.FreeFallINT(1);
  adxl.doubleTapINT(1);
  adxl.singleTapINT(1);

//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING); // Присоединить прерывание

}

/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

  // Показания акселерометра
  int x,y,z;   
  adxl.readAccel(&x, &y, &z);         // Чтение значений акселерометра и сохранение их в объявленных выше переменных x,y,z

  // Вывод результатов в последовательный порт
  /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
  Serial.print(x);
  Serial.print(", ");
  Serial.print(y);
  Serial.print(", ");
  Serial.println(z); 

// ADXL_ISR();
  // Вы также можете не использовать прерывания и просто запускать функции в ADXL_ISR();
  // и вместо этого поместите его в цикл.
  // Это может пригодиться, когда не имеет значения, когда происходит действие.

}

/********************* ISR *********************/
/* Look for Interrupts and Triggered Action    */
void ADXL_ISR() {

  // getInterruptSource очищает все запущенные действия после возврата значения
  // Не вызывайте снова, пока вам не понадобится перепроверить сработавшие действия
  byte interrupts = adxl.getInterruptSource();

  // Обнаружение свободного падения
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //добавьте сюда код, который будет выполняться при обнаружении свободного падения
  } 

  // Бездействие
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    Serial.println("*** INACTIVITY ***");
     //добавьте сюда код, который будет выполняться при обнаружении бездействия
  }

  // Активность
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***"); 
     //добавьте сюда код, который будет выполняться при обнаружении активности
  }

  // Обнаружение двойного касания
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     //добавьте сюда код, который будет выполняться при обнаружении двойного касания
  }

  // Обнаружение нажатия
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
     //добавьте сюда код, который будет выполняться при обнаружении касания
  } 
}
,