Помогите с концепцией bluetooth логгера метеоданных

shirushizo
Offline
Зарегистрирован: 10.05.2015

Доброго времени суток!

Я прикладной программист, с микроконтроллерами и чистым Си дружу не особо.

Очень хочется услышать Ваши советы и конструктивную критику по выбору библиотек, архитектуре кода и реализации отдельных моментов.

Есть следующая задача: разработать максимально автономный логгер метеоданных с возможностью снятия показаний через bluetooth, клиентами будут Andorid-устройства.

Аппаратная часть:

 - Arduino Uno;

 - DHT11;

 - Часы реального времени на чипе DS1307;

 - Bluetooth HC-06;

 - MicroSD card reader с SPI;

 - Proto Shield.

Уже есть Arduino Uno и DHT11, остальное - жду. DHT11 думаю заменить на DHT22 или DS18B20.

Идея микропрограммы:

Снимаем данные с датчика влажности и температуры через определенные интервалы (минута и более), записываем данные во внешнюю память и уходим в спячку.

Если кто-то подключился через bluetooth, начинаем сеанс обмена. Набор команд придумал небольшой:

 - получение состояния логгера, версии микропрограммы;

 - получение текущих значений;

 - получение данных из внешней памяти;

 - установка даты/времени;

 - установка параметров (интервал опроса и прочее).

На данный момент:

Научился снимать показания с DHT11, читать/писать в последовательный порт. Завис на прерываниях, таймерах и режимах работы микроконтроллера.

Хочу понять:

 - какой оптимальны режим энергосбережения для моего случая;

 - как менять режим по событию таймера и при подключении клиента;

 - какие библиотеки для работы использовать;

 - что я не учел при проектировании.

Буду рад любой помощи.

Maverik
Offline
Зарегистрирован: 12.09.2012

приличного энергосберегающего режима не получится, т.к. чтобы в любой момент кто-то мог подключиться по блютуз, этот самый блютуз должен постоянно быть активен.  сам по себе опрос датчика влажности или температуры по сравнению с блютуз ничего не жрет. не совсем понятно что вы собираетесь измерять. днт11, 22 предназначены  для влажности,  18б20 измеряет температуру.

с логгером в вашем случае проблем быть недолжно. иногда приключаются танцы с бубном если работа с сд-картой сочетается с передачей данных по езернет (езернет-шилд w5100 у которого на борту и сетевой контроллер и сд-слот ), у этого контроллера желательно не задействовать обе библиотеки одновременно, лучше поочередно.

shirushizo
Offline
Зарегистрирован: 10.05.2015

Maverik, спасибо за ответ. Какое примерно соотношение энергопотребления у bluetooth в режиме ожидания и микроконтроллера, который висит в loop() и ждет подключение, переодически опрашивает DHT? (код прикрепил ниже)

Задача измерять температуру, влажность- вдовесок, раз DHT умеет его измерять.

На данные момент считаю millis() и жду получения символа в последовательный порт в loop(), а через заданные интервалы времени считываю значения с DHT.

Не понятны следующие моменты:

1. Как мне кажется, это все избыточно и чтение порта лучше вынести в обработку прирывания?

2. Как уводить микроконтроллер в спячку между опросами и будет ли от этого толк, учитывая что перед снятием значений с DHT идет какая-то его инициализация?

3. Можно ли питать bluetooth через ногу микроконтроллера, если используется режим сна?

Заранее спасибо за ответы.

Микропрограмма:

#include <dht11.h>
#define DHT11_PIN 4

dht11 DHT11;
// храним время последнего опроса, в мс
unsigned long previous_request_millis = 0;        
// интервал между опросами, в мс
const int interval_millis = 30 * 1000;           
int current_humidity = 0;
int current_temperature = 0;

void read_command(void)
{
  if (Serial.available() > 0)
  {
    int incoming_command = Serial.read();
    Serial.print(millis());
    Serial.print(",\t");
    switch(incoming_command)
    {
      case '1':
      // проверка связи
      // отладочный вывод
      Serial.println('1');
      break;
      case '2':
      // получение версии микропрогаммы и имени прибора
      // отладочный вывод
      Serial.println('2\t version: 1.0.0 name: sensor 1');
      break;
      case '3':
      // получение текущих значений
      // отладочный вывод
      Serial.print('3\t current values:');
      Serial.print(current_humidity, 1);
      Serial.print(",\t");
      Serial.println(current_temperature, 1);        
      break;
      case '4':
      /* получение значений из лога */
      // отладочный вывод
      Serial.println('4\t log: empty');
      break;
      case '5':
      /* чтение настрочных параметров */
      // отладочный вывод
      Serial.println('5\t');
      break;
      case '6':
      /* запись настрочных параметров */
      // отладочный вывод
      Serial.println('6\t');
      break;
      case '7':
      /* чтение даты/времени */
      // отладочный вывод
      Serial.println('7\t');
      break;
      case '8':
      /* установка значений даты/времени */
      // отладочный вывод
      Serial.println('8\t');
      break;
      default:
      // отладочный вывод
      Serial.print("Unknown command,\t");
      Serial.println(incoming_command);
    } // switch(incoming_command)
  } // Serial.available() > 0
}

void setup(void)
{
  Serial.begin(9600);
}

void loop(void)
{
  // получаем текущее значени millis и сравниваем с временем предыдущего пороса
  unsigned long current_millis = millis();
  if(current_millis - previous_request_millis > interval_millis)
  {
    // сохраняем время опроса
    previous_request_millis = current_millis; 
 
    // опроса датчика
    int check = DHT11.read(DHT11_PIN);
    // отладочный вывод
    Serial.print(current_millis);
    Serial.print(",\t");
    switch (check)
    {
      case DHTLIB_OK:
        // читаем значения с DHT11
        current_humidity = DHT11.humidity;
        current_temperature = DHT11.temperature;
        /* пишем данные в лог */
        // отладочный вывод
        Serial.print(current_humidity, 1);
        Serial.print(",\t");
        Serial.println(current_temperature, 1);
        break;
      case DHTLIB_ERROR_CHECKSUM:
        /* пишем ошибку в лог */
        // отладочный вывод
        Serial.println("Checksum error,\t");
        break;
      case DHTLIB_ERROR_TIMEOUT:
        // отладочный вывод
        /* пишем ошибку в лог */
        Serial.println("Time out error,\t");
        break;
      default:
        /* пишем ошибку в лог */
        // отладочный вывод
        Serial.println("Unknown error,\t");
    }
  }
  
  //не было ли команд
  read_command();
}

 

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

 

Блютуз напрямую питать от ножки нельзя, только если транзистором; у НС-05 есть вывод EN, при подаче на него низкого лог.уровня, модуль вырубается

shirushizo
Offline
Зарегистрирован: 10.05.2015

Yarik.Yar, я, наверно, не так выразился. Я имел ввиду выводы Arduino Uno 5/3,3 В, скорее всего это нога стабилитрона, а не микрокотроллера - увы, в аппартной части разбираюсь еще хуже программной. Имелось ввиду, будет ли питания у модуля HC-05, если микрокотроллер будет в спячке, и смогут ли при этом подключаться клиенты?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

 

 

Стабилизатор напряжения на плате от контроллера никак не зависит:)

shirushizo
Offline
Зарегистрирован: 10.05.2015

Yarik.Yar, с этим мы уже разобрались выше=)

Сейчас вопрос в том, как повесить чтение команд из последовательного порта на соответствующее прерывание, чтоб не дергать его каждый вызов loop().

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

 

Во-первых, можно сделать внутреннее прерывание по поступившим данным, а можно соединить RX и 2 выход - это будет внешнее прерывание)

shirushizo
Offline
Зарегистрирован: 10.05.2015

Yarik.Yar, спасибо за ответ. Что прерывание нужно использовать - факт, я вроде даже нашел как это сделать.

Переживаю по поводу длительных операций, типа чтения лога с SD-карты, чтоб опрос датчика не пропустить. Может опрос DHT11 вынести в прерывание с большим приоритетои, чем UART.

Самое печальное - нет всей переферии для тестов, а устройство хотят показать руководству через неделю=)

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

 

Есть DHT,адаптер для карты , модуль блютуза - могу протестировать;)

shirushizo
Offline
Зарегистрирован: 10.05.2015

Yarik.Yar, ценю Вашу заботу, но с моим уровнем только разработка через отладку=) Нашел у себя в городе (Ростов-на-Дону) магазинчик, может за пару дней купят - будет чуть попроще.

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

=)