Моя настройка двух ведомых SPI на arduino не работает правильно

Я пытаюсь подключить DPS310 и ADXL345 к моему Arduino с помощью 4-проводного SPI. При индивидуальном тестировании (т. е. у каждого свой сценарий) вывод правильный, однако при объединении сценариев вывод ADXL — мусор, но DPS работает.

Что мы ожидаем увидеть:

Температура = 24,14 *C
Давление = 857,88 гПа
Х: -4 У: 4 З: 29

Что мы видим на самом деле:

Температура = 24,14 *C
Давление = 857,88 гПа
X:0 Y:0 Z:0 // и не меняется при наклоне

Когда строка DPS310 закомментирована, ADXL работает нормально (эта строка указана в скрипте)

Весь скрипт (с указанием ошибочной строки):

#include <SparkFun_ADXL345.h>
#include <Adafruit_DPS310.h>

// объект ADXL
#define ADXL345_CS   9 // контакт SPI
ADXL345 ADXL = ADXL345_CS; // Создаем объект obj с выводом CS
int x = 0, y = 0, z = 0; 

// Объект ДПС
#define DPS310_CS   10 // вывод SPI
Adafruit_DPS310 dps; // Создаем объект obj (пин задается в настройках)
sensors_event_t temp_event, pressure_event; 

void setup() {
   Serial.begin(115200);
   while (!Serial) delay(10);

   // НАСТРОЙКА ADXL
   digitalWrite(ADXL345_CS, LOW); // НАЧАТЬ СВЯЗЬ
   Serial.print("ADXL345: ");
   ADXL.powerOn();
   delay(50);
   ADXL.setRangeSetting(16); 
   ADXL.setSpiBit(0);
   ADXL.set_bw(ADXL345_BW_12_5); 
   ADXL.setInterrupt(0x84, true);
   ADXL.setAxisOffset(0, 0, 5);
   ADXL.readAccel(&x, &y, &z);
   if(x != -1 && y != -1 && z != -1) {
     Serial.println("[PASSED]");
   } else {
     Serial.println("[FAILED]");
   }
   digitalWrite(ADXL345_CS, HIGH); // КОНЕЦ СВЯЗИ

   // НАСТРОЙКА ДПС
   digitalWrite(DPS310_CS, LOW); // НАЧАТЬ СВЯЗЬ
   Serial.print("DPS310: ");
   if (! dps.begin_SPI(DPS310_CS)) { /////////////////ЗДЕСЬ ПРОБЛЕМА//////////////////
      Serial.println(" [FAILED]");
   }
   Serial.println(" [PASSED]");

   dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
   dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);
   digitalWrite(DPS310_CS, HIGH); // КОНЕЦ СВЯЗИ
}

void loop() {
    digitalWrite(ADXL345_CS, LOW);
    ADXL.readAccel(&x, &y, &z);
    digitalWrite(ADXL345_CS, HIGH);

    digitalWrite(DPS310_CS, LOW);
    dps.getEvents(&temp_event, &pressure_event);
    digitalWrite(DPS310_CS, HIGH);
    
    Serial.print("Temperature = ");
    Serial.print(temp_event.temperature);
    Serial.println(" *C");
    Serial.print("Pressure = ");
    Serial.print(pressure_event.pressure);
    Serial.println(" hPa"); 

    Serial.print("X: ");
    Serial.print(x);
    Serial.print("  Y: ");
    Serial.print(y);
    Serial.print("  Z: ");
    Serial.println(z);

    delay(50);
}

Я думаю, что проблема может заключаться в классах, написанных для этих устройств, например, может быть, они были написаны для одного устройства SPI или имеют разные частоты/режимы? (Хотя я, наверное, ошибаюсь XD). Я еще не пробовал настраивать SPI для каждого устройства вручную (заповедь программирования: не изобретать велосипед), поэтому буду очень признателен за любую помощь.

, 👍1

Обсуждение

установите вывод CS второго устройства в ВЫСОКИЙ уровень перед инициализацией первого устройства, @Juraj

@Juraj Я только что попробовал, и это не удалось. Даже пытался поставить как HIGH, так и задержку на 2 секунды перед инициализацией чего-либо., @newt


1 ответ


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

1

ADXL345 использует SPI_MODE3, а DPS310 — SPI_MODE0. Библиотеки для этих устройств не используют транзакции SPI, а задают настройки только в begin(), поэтому они нельзя использовать вместе.

Вы можете решить эту проблему либо подключить один датчик к программному SPI, либо подключить один или оба датчика к I2C.

ADXL345 можно использовать как устройство I2C. Его библиотека поддерживает I2C с конструктором, когда параметры не указаны. Есть ли у вашего модуля возможность подключить его к I2C?

Библиотека Adafruit для DPS310 имеет встроенный программный SPI, поэтому вы можете использовать ее с любым набором выводов. И он также поддерживает I2C.

,

Я боялся этого, есть идеи, как я могу изменить библиотеки, чтобы они работали друг с другом? Я попытался написать базовый сценарий SPI для выполнения транзакций, следуя тому, что делают библиотеки, однако библиотеки слишком сложны для меня, и поэтому это было безрезультатно. Или мне лучше попытаться реализовать свой собственный независимый сценарий SPI (имея в виду, что я очень новичок в этом)?, @newt

@newt, я улучшил ответ, @Juraj

Спасибо, переключил ADXL на I2C и оставил DPS в режиме SPI, и все заработало!, @newt