Использование датчика температуры LM70 с Arduino

arduino-mega spi temperature

Я пытаюсь измерить температуру с помощью датчика температуры LM70 с Arduino Mega. Как вы можете видеть в таблице данных, он использует протокол SPI. Я выполнил следующие подключения (пакет VSSOP-8):

  • Контакт SI/O --> Пин 50 Ардуино Мега.
  • Значок SC --> Пин 52 Ардуино Мега.
  • Контакт CS --> Пин 53 Arduino Mega.
  • Контакт V+ --> 3,3 В Ардуино Мега.
  • Контакт заземления --> Земля Arduino Mega.

Мой код не работает (не печатает нужную температуру), и я думаю, что это может быть по двум причинам:

  1. Я неправильно считываю информацию с датчика. Он отправляет 16 бит, из которых первые 11 бит хранят данные о температуре.
  2. Я неправильно рассчитываю температуру.

Это мой код:

// датчик общается по SPI, поэтому подключаем библиотеку:
#include <SPI.h>

void setup() {
  pinMode(51,OUTPUT); //МОСИ
  pinMode(50,INPUT); //МИСО
  pinMode(52,OUTPUT); //ЧАСОВОЙ ПИН
  digitalWrite(53,HIGH); // выбор ведомого остается высоким. Когда мы установим это значение на низкое, датчик начнет отправлять данные.
  SPI.begin();
  Serial.begin(9600);

  //время настраивать
  delay(500);
}

void loop() {
    //включить подчиненный
    digitalWrite(A0,LOW); //Включить связь с подчиненным
    delay(500); // ждем конверсии
    
    int val = SPI.transfer(0x00); // чтение с датчика
    Serial.println(val); //отображение показаний на последовательном мониторе
    int temperature = val * 0.25;
    Serial.println(temperature); //отображаем температуру на последовательном мониторе


    //отключить ведомое устройство
    digitalWrite(53,HIGH); // установить снова на высокий уровень
}

Пожалуйста, если вы видите что-то не так в моем коде, дайте мне знать. Заранее спасибо.

, 👍1

Обсуждение

digitalWrite(A0,LOW) -- Вы *уверены* в этом?, @Majenko

Вы правы, это должно быть digitalWrite(53, LOW). Спасибо!!! Однако код по-прежнему не работает. Любые идеи?, @Fakiko


2 ответа


2

Есть несколько вещей, которые работают неправильно. Это не полный ответ, но он дает вам некоторые указания, как сделать это правильно.

  1. A0 — это контакт 54, а не SS, который является контактом 53;

  2. О том, как правильно использовать библиотеку SPI, я бы посоветовал вам прочитать мой блог на странице SPI, это также поможет вам получить данные из таблицы данных, необходимые для программирования SPI. На основе временной диаграммы в таблице данных вам необходимо настроить SPI как SPI_MODE2;

  3. Вывод SI/O LM70 используется как MOSI, так и MISO, вам нужно будет подключить MOSI к SI/O через резистор 10 кОм, а SI/O подключить напрямую к MISO. Эта информация доступна в данных лист;

  4. Температурные данные LM70 представлены в формате дополнения до двух. Чтобы преобразовать их, требуется немного Работа. Затем необходимо сдвинуться вниз/вправо с помощью оператора bitshift на 5 бит, чтобы поехать из первых 5 бит, прежде чем, наконец, умножить на 0,25C в соответствии со спецификацией.

int value = 0x4b1f;  // значение из SPI, temp = 125 градусов C
int mask = 0x8000;   // маска для старшего разряда
int temp = (-(value & mask) + (value & ~mask)) >> 5;
Serial.print("Temp");
Serial.println(temp*.25);

Прочитайте все ссылки, которые я предоставил, чтобы понять тему, и попробуйте. Удачи!

,

1

Ваша проблема здесь:

    int val = SPI.transfer(0x00); // чтение с датчика
    Serial.println(val); //отображение показаний на последовательном мониторе
    int temperature = val * 0.25;

И это двойная проблема.

Во-первых:

int val = SPI.transfer(0x00);

При этом считываются только первые 8 бит данных. Чтобы получить все 16 бит, вам нужно сделать две передачи, а затем объединить их с помощью битового сдвига:

int bh = SPI.transfer(0x00);
int bl = SPI.transfer(0x00);
int val = (bh << 8) | bl;

Это даст вам значение, выровненное по правому краю. затем вам нужно сдвинуть его влево на нужное количество битов и "расширить знак" это, чтобы держать его отрицательным, если это необходимо. Если вас не интересует дробная часть, то это так же просто, как:

val >>= 7;
if (val & 0x0100) {
    val |= 0xFE00;
}

Теперь... что все это значит? Ну, предположим, сейчас 25°C. Из таблицы данных мы можем видеть, что это даст нам чтение 0000 1100 1001 1111 (обратите внимание, что в таблице данных есть опечатка, говорящая, что 0b9f в шестнадцатеричном формате, хотя на самом деле это 0c9f).

Давайте проделаем эти операции — сначала побитовый сдвиг:

Dec   Hex   Bin
3231  0C9F  0000110010011111 >> 7
25    0019  0000000000011001

Затем мы проверяем, установлен ли бит 8 или нет (бит 8 был старшим битом). Если это так, то мы также устанавливаем ИЛИ с битами 9-15. Этот "знак расширяется" это.

Давайте посмотрим на -25°C из таблицы данных:

Dec   Hex  Bin
-3169 f39f 1111001110011111 >> 7      Shift right 7 bits
487   01e7 0000000111100111 & 0x0100  And with 8th bit
256   0100 0000000100000000           Result is not 0 so is true

"Or" the shifted value with 0xFE00:

487   01e7 0000000111100111 or
65024 fe00 1111111000000000 =
-25   ffe7 1111111111100111
,