Arduino:Примеры/BarometricPressureSensor

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

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Использование 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

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