Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/BarometricPressureSensor

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Использование SPI в считывании данных от датчика атмосферного давления[1]

Этот пример показывает, как использовать библиотеку SPI (Serial Peripheral Interface, т.е. «последовательный периферийный интерфейс») для считывания данных с датчика атмосферного давления SCP1000. Больше информации о SPI можно прочесть здесь.

Необходимое оборудование

  • Плата с датчиком атмосферного давления SCP1000;
  • Плата Arduino;
  • Макетная плата Breadboard или плата для прототипирования;

Цепь

BaromettricPressureSensor bb.png

Схема

BaromettricPressureSensor sch.png

Датчик SCP1000 может считывать как атмосферное давление, так и температуру, а затем передавать эти данные через SPI. Более подробно о регистрах управления смотрите в «даташите» SCP1000.

В скетче ниже Arduino начинает с настройки регистров конфигурации SCP1000 – это происходит в блоке setup(). Далее в loop() он настраивает датчик таким образом, чтобы тот считывал данные в режиме высокого разрешения. Это значит, что данные об атмосферном давлении будут возвращены в 19-битном значении, а о температуре – в 16-битном. Далее это 16-битное значение будет поделено на 20, чтобы получить температуру в градусах по Цельсию, а затем показано на Serial Monitor.

Разобравшись с температурой, скетч возьмется за данные о давлении. Он будет считывать их в два этапа: сначала «верхние» 3 бита, а затем «нижние» 16. Далее он сольет эти два значения в одну целочисленную переменную – сначала сдвинет первые 3 бита при помощи битового сдвига, а потом соединит их с оставшимися 16 битами при помощи побитового «ИЛИ». Затем это 19-битное значение будет поделено на 4, чтобы получить давление в Паскалях.

  1. /*
  2. Показ данных от датчика атмосферного давления SCP1000
  3.  
  4. Показывает на Serial Monitor данные от датчика атмосферного давления.
  5. Использует библиотеку SPI. Более подробно об SCP1000 читайте тут:
  6. http://www.sparkfun.com/commerce/product_info.php?products_id=8161
  7. http://www.vti.fi/en/support/obsolete_products/pressure_sensors
  8.  
  9. Скетч адаптирован к SCP1000-примеру Нейтана Зидле (Nathan Seidle) для PIC:
  10. http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
  11.  
  12. Цепь:
  13. * Датчик SCP1000 подсоединен к 6-ому, 7-ому, 10-ому, 11-ому, 12-ому и 13-ому контактам Arduino
  14. * DRDY – 6-ой контакт
  15. * CSB – 7-ой контакт
  16. * MOSI – 11-ый контакт
  17. * MISO – 12-ый контакт
  18. * SCK – 13-ый контакт
  19.  
  20. Создан 31 июля 2010,
  21. модифицирован 14 августа 2010 Томом Иго (Tom Igoe).
  22. */
  23.  
  24. // Датчик коммуницирует через SPI, поэтому подключаем соответствующую библиотеку:
  25. #include <SPI.h>
  26.  
  27. // Адреса регистров памяти SCP1000:
  28. const int PRESSURE = 0x1F;      // 3 самых важных бита в данных о давлении
  29. const int PRESSURE_LSB = 0x20;  // 16 менее важных бита в данных о давлении
  30. const int TEMPERATURE = 0x21;   // 16 битов данных о температуре
  31. const byte READ = 0b11111100;     // команда считывания для SCP1000
  32. const byte WRITE = 0b00000010;   // команда записи для SCP1000
  33.  
  34. // Контакты, используемые для подключения датчика.
  35. // (все остальные используются для управления библиотекой SPI):
  36. const int dataReadyPin = 6;
  37. const int chipSelectPin = 7;
  38. void setup() {
  39.   Serial.begin(9600);
  40.  
  41.   // Запускаем библиотеку SPI:
  42.   SPI.begin();
  43.  
  44.   // Инициализируем контакты Data Ready и Chip Select:
  45.   pinMode(dataReadyPin, INPUT);
  46.   pinMode(chipSelectPin, OUTPUT);
  47.  
  48.   // Конфигурируем SCP1000 таким образом, чтобы итоговые данные были менее «шумными»:
  49.   writeRegister(0x02, 0x2D);
  50.   writeRegister(0x01, 0x03);
  51.   writeRegister(0x03, 0x02);
  52.   // Даем датчику время настроиться:
  53.   delay(100);
  54. }
  55.  
  56. void loop() {
  57.   // Выбираем режим высокого разрешения:
  58.   writeRegister(0x03, 0x0A);
  59.  
  60.   // Ничего не делаем до тех пор, пока контакт Data Ready не получит значение HIGH:
  61.   if (digitalRead(dataReadyPin) == HIGH) {
  62.     // Считываем данные о температуре:
  63.     int tempData = readRegister(0x21, 2);
  64.  
  65.     // Конвертируем их в градусы Цельсия и отображаем на Serial Monitor:
  66.     float realTemp = (float)tempData / 20.0;
  67.     Serial.print("Temp[C]=");  //  "Температура[Цельсии]="
  68.     Serial.print(realTemp);
  69.  
  70.  
  71.     // Считываем 3 «верхних» бита в данных о давлении:
  72.     byte  pressure_data_high = readRegister(0x1F, 1);
  73.     pressure_data_high &= 0b00000111; // вам нужны только биты с 0-ого по 2-ой
  74.  
  75.     // Считываем «нижние» 16 битов в данных о давлении:
  76.     unsigned int pressure_data_low = readRegister(0x20, 2);
  77.     // Соединяем обе части в 19-битное число:
  78.     long pressure = ((pressure_data_high << 16) | pressure_data_low)/4;
  79.  
  80.     // Показываем давление:
  81.     Serial.println("\tPressure [Pa]=" + String(pressure));  // "\tДавление[Паскали]="
  82.   }
  83. }
  84.  
  85. // считываем или записываем данные в регистр SCP1000:
  86. unsigned int readRegister(byte thisRegister, int bytesToRead ) {
  87.   byte inByte = 0;           // входящий байт от SPI
  88.   unsigned int result = 0;   // возвращенный результат
  89.   Serial.print(thisRegister, BIN);
  90.   Serial.print("\t");
  91.   // SCP1000 ждет, что имя регистра будет в «верхних» 6 битах байта,
  92.   // поэтому смещаем биты влево на два бита:
  93.   thisRegister = thisRegister << 2;
  94.   // Теперь соединяем адрес и команду в один байт:
  95.   byte dataToSend = thisRegister & READ;
  96.   Serial.println(thisRegister, BIN);
  97.   // Даем контакту Chip Select значение LOW, чтобы выбрать девайс:
  98.   digitalWrite(chipSelectPin, LOW);
  99.   // Отсылаем девайсу регистр, который вы хотите сосчитать:
  100.   SPI.transfer(dataToSend);
  101.   // Отсылаем значение «0», чтобы сосчитать первый возвращенный байт:
  102.   result = SPI.transfer(0x00);
  103.   // Уменьшаем количество байтов, которые осталось прочитать:
  104.   bytesToRead--;
  105.   // Если еще остались байты, которые можно прочесть... :
  106.   if (bytesToRead > 0) {
  107.     // ...сдвигаем первый байт влево и берем второй байт:
  108.     result = result << 8;
  109.     inByte = SPI.transfer(0x00);
  110.     // Соединяем байт, который мы только что взяли, с предыдущим:
  111.     result = result | inByte;
  112.     // Уменьшаем количество байтов, который осталось прочесть:
  113.     bytesToRead--;
  114.   }
  115.   // Даем контакту Chip Select значение LOW, чтобы отменить выбор девайса:
  116.   digitalWrite(chipSelectPin, HIGH);
  117.   // Возвращаем результат:
  118.   return(result);
  119. }
  120.  
  121.  
  122. // Эта функция отправляет на SCP1000 команду записи:
  123. void writeRegister(byte thisRegister, byte thisValue) {
  124.  
  125.   // SCP1000 ждет, что адрес регистра будет в «верхних» 6 битах байта,
  126.   // поэтому сдвигаем биты влево на две позиции:
  127.   thisRegister = thisRegister << 2;
  128.   // Теперь соединяем адрес регистра и команду в одном байте:
  129.   byte dataToSend = thisRegister | WRITE;
  130.  
  131.   // Даем контакту Chip Select значение LOW, чтобы выбрать девайс:
  132.   digitalWrite(chipSelectPin, LOW);
  133.  
  134.   SPI.transfer(dataToSend); // отсылаем месторасположение регистра
  135.   SPI.transfer(thisValue);  // отсылаем значение, которое будет записано в регистр
  136.  
  137.   // Даем контакту Chip Select значение HIGH, чтобы отменить выбор девайса:
  138.   digitalWrite(chipSelectPin, HIGH);
  139. }

См.также

  1. Arduino SPI LIbrary
  2. SPIDigitalPot

Внешние ссылки

  1. Arduino - Using SPI to read a Barometric Pressure Sensor