SPI Проблема Arduino Mega с датчиком давления MS5803-05BA - PullRequest
0 голосов
/ 14 марта 2020

Мне нужна ваша помощь для проекта.

На самом деле у меня есть 2 параллельных датчика типа: MS5803-05BA, который поддерживает I2 C и соединение SPI. Один датчик находится на шине I2 C, а другой - на SPI. Они оба отправляют в мой Arduino Mega. I2 C отлично работает с короткими кабелями.

Вот таблица данных датчика: https://www.amsys.de/downloads/data/MS5803-05BA-AMSYS-datasheet.pdf

Для некоторых сведений, которые хотят сделать то же самое с I2 C. Здесь вы можете найти хороший код. (Вы можете найти и другие типы MS580X). Для связи между датчиком и Arduino Mega вам понадобится конвертер logi c, подобный этому txs0108e, который можно купить с платой отключения (вам нужны подтягивающие резисторы на стороне датчика!):

https://github.com/millerlp/MS5803_05

Но к моей проблеме: у меня расстояние датчика около 3-5 метров, а соединения I2 C не работают. Да, я могу попытаться исправить подтягивающие резисторы, но у меня это не сработало (я пробовал несколько разных более низких резисторов в диапазоне 3-10 кОм) Поэтому я хочу переключиться на шину SPI.

Я изменил код с https://github.com/millerlp/MS5803_05, https://github.com/vic320/Arduino-MS5803-14BA и https://arduino.stackexchange.com/questions/13720/teensy-spi-and-pressure-sensor.

Файл добавлен. (Вы должны поместить файлы .h и. cpp в папку кода Arduino (.spi).

У меня проблемы с кодом из SPI (ccp и header). Нет правильная связь. Я дважды проверил свои кабели. Не смог найти проблему, и соединение с txs0108e работает для параллельного датчика I2 C. Оба датчика работают на I2 C.

Вот основной код (arduino .spi) для SPI и I2 C параллельно:

/_____ I N C L U D E S
#include <stdio.h>
#include <math.h>
#include <SPI.h>
#include <Wire.h>
#include "MS5803_05.h"
#include "MS5803_05_SPI.h"


const int miso_port = 50; //SDI
const int mosi_port = 51; //SDO
const int sck_port = 52;  //SLCK
const int slaveSelectPin = 53; // CSB

MS_5803 sensor = MS_5803(512);
MS_5803_SPI sensor_spi = MS_5803_SPI(4096, slaveSelectPin);


void setup()
{
  pinMode(miso_port, INPUT);
  pinMode(mosi_port, OUTPUT);
  pinMode(slaveSelectPin, OUTPUT);
  pinMode(sck_port, OUTPUT);  

  Serial.begin(9600);
  //SPI BUS
  if (sensor_spi.initializeMS_5803_SPI()) {
    Serial.println( "MS5803 SPI CRC check OK." );
  }
  else {
    Serial.println( "MS5803 SPI CRC check FAILED!" );
  }  

  //I2C BUS
  delay(1000);
  if (sensor.initializeMS_5803()) {
    Serial.println( "MS5803 I2C CRC check OK." );
  }
  else {
    Serial.println( "MS5803 I2C CRC check FAILED!" );
  }  

}

void loop()
{
  Serial.println("SPI Sensor first pressure [mbar], than temperature[°C]:");
  sensor_spi.readSensor();

  // Show pressure
  Serial.print("Pressure = ");
  Serial.print(sensor_spi.pressure());
  Serial.println(" mbar");

  // Show temperature
  Serial.print("Temperature = ");
  Serial.print(sensor_spi.temperature());
  Serial.println("C");

  ////********************************************************
  Serial.println("");

  Serial.println("I2C Sensor first pressure [mbar], than temperature[°C]:");
  sensor.readSensor();
  // Show pressure
  Serial.print("Pressure = ");
  Serial.print(sensor.pressure());
  Serial.println(" mbar");

  // Show temperature
  Serial.print("Temperature = ");
  Serial.print(sensor.temperature());
  Serial.println("C");

  delay(2000);
}
}

Первое соединение с SPI здесь (. cpp):


#include "MS5803_05_SPI.h"
#include <SPI.h>

#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC resolution=256
#define CMD_ADC_512 0x02 // ADC resolution=512
#define CMD_ADC_1024 0x04 // ADC resolution=1024
#define CMD_ADC_2048 0x06 // ADC resolution=2048
#define CMD_ADC_4096 0x08 // ADC resolution=4096
#define CMD_PROM_RD 0xA0 // Prom read command

#define spi_write SPI_MODE3
#define spi_write2 SPI_MODE1

// Create array to hold the 8 sensor calibration coefficients
static unsigned int      sensorCoeffs[8]; // unsigned 16-bit integer (0-65535)
// D1 and D2 need to be unsigned 32-bit integers (long 0-4294967295)
static uint32_t     D1 = 0;    // Store uncompensated pressure value
static uint32_t     D2 = 0;    // Store uncompensated temperature value
// These three variables are used for the conversion steps
// They should be signed 32-bit integer initially
// i.e. signed long from -2147483648 to 2147483647
static int32_t dT = 0;
static int32_t TEMP = 0;
// These values need to be signed 64 bit integers
// (long long = int64_t)
static int64_t Offset = 0;
static int64_t Sensitivity  = 0;
static int64_t T2 = 0;
static int64_t OFF2 = 0;
static int64_t Sens2 = 0;

// Some constants used in calculations below
const uint64_t POW_2_33 = 8589934592ULL; // 2^33 = 8589934592
SPISettings settings_write(500000, MSBFIRST, spi_write);
SPISettings settings_write2(500000, MSBFIRST, spi_write2);

//-------------------------------------------------
// Constructor
MS_5803_SPI::MS_5803_SPI( uint16_t Resolution, uint16_t cs) {
 // The argument is the oversampling resolution, which may have values
 // of 256, 512, 1024, 2048, or 4096.
 _Resolution = Resolution;
  //Chip Select
  _cs=cs;
}

boolean MS_5803_SPI::initializeMS_5803_SPI(boolean Verbose) {
      digitalWrite( _cs, HIGH );
      SPI.begin();
      // Reset the sensor during startup
      resetSensor();

      if (Verbose)
      {
       // Display the oversampling resolution or an error message
       if (_Resolution == 256 | _Resolution == 512 | _Resolution == 1024 | _Resolution == 2048 | _Resolution == 4096){
           Serial.print("Oversampling setting: ");
           Serial.println(_Resolution);    
       } else {
   Serial.println("*******************************************");
   Serial.println("Error: specify a valid oversampling value");
   Serial.println("Choices are 256, 512, 1024, 2048, or 4096");
   Serial.println("*******************************************");
       }

      }  

      // Read sensor coefficients
      for (int i = 0; i < 8; i++ )
      {
        SPI.beginTransaction(settings_write2);
        digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low          
        unsigned int ret;
        unsigned int rC = 0;        
        SPI.transfer(CMD_PROM_RD + i * 2); // send PROM READ command
        /*
        ret = SPI.transfer(0x00); // send 0 to read the MSB
        rC = 256 * ret;
        ret = SPI.transfer(0x00); // send 0 to read the LSB
        rC = rC + ret;    
        */
        // send a value of 0 to read the first byte returned:
        rC = SPI.transfer( 0x00 );
        rC = rC << 8;
        rC |= SPI.transfer( 0x00 ); // and the second byte        
       sensorCoeffs[i] = (rC);

        digitalWrite( _cs, HIGH );
        delay(3);
    }
    //SPI.endTransaction(); // interrupt can now be accepted
    // The last 4 bits of the 7th coefficient form a CRC error checking code.
    unsigned char p_crc = sensorCoeffs[7];
    // Use a function to calculate the CRC value
    unsigned char n_crc = MS_5803_CRC(sensorCoeffs);

    if (Verbose) {
      for (int i = 0; i < 8; i++ )
      {
        // Print out coefficients
        Serial.print("C");
        Serial.print(i);
        Serial.print(" = ");
        Serial.println(sensorCoeffs[i]);
        delay(10);
      }      
   Serial.print("p_crc: ");
   Serial.println(p_crc);
   Serial.print("n_crc: ");
   Serial.println(n_crc);
    }
    // If the CRC value doesn't match the sensor's CRC value, then the
    // connection can't be trusted. Check your wiring.
    if (p_crc != n_crc) {
        return false;
    }
    // Otherwise, return true when everything checks out OK.
    return true;
}
// Sends a power on reset command to the sensor.
void MS_5803_SPI::resetSensor() {
  SPI.beginTransaction(settings_write);
  digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low to start the command
  SPI.transfer(CMD_RESET); // send reset sequence
  delay(3); // wait for the reset sequence timing delay(3)
  digitalWrite(_cs, HIGH); //csb_hi(); // pull CSB high to finish the command
  SPI.endTransaction(); // interrupt can now be accepted
}

Код может можно загрузить по адресу: https://forum.arduino.cc/index.php?topic=670661.0 Там вы можете найти схемы c и изображение вывода.

Большое спасибо:).

...