Датчик температуры и влажности и Processing

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

 Добрый всем день.

Такой вопрос.

Есть датчик DHT-11.,ардуино МЕГА 2560., компьютер.

Нужно написать программу на Процессинге с использованием стандарта Firmata.

Суть вопроса - как используя протокол фирмата чтобы получать данные с этого датчика. Что то сообразить не могу.

Мож ссылочка есть на пример.

      
leshak
Offline
Зарегистрирован: 29.09.2011

 В лоб - никак. У него вообщем-то другое предназначение.  В нем вы работаете с "состоянием пинов", а не "датчиками и произвольными данными".

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

Ну то есть, если "очень хочется", можно конечно будет "прикрутить фирмату". На стороне ардуины, обработать датчик и как-то "прикинутся аналоговым пином". Но это, скорее всего, потребует разбирательств с протоколом и хакингом библиотеки.

Вообщем, IMHO, гораздо проще будет взять библиотеку (для ардуины) этого датчика, считать с него данные и послать их проценнигу обычным Serila.print или Serial.write, без "протоколов". Фактически сделать какой-то свой очень "упрощенный протокол".  

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

 leshak, да да, огромное спасибо - я вот уже сам к этому пришел.  Буду пробовать обрабатывать сигналы с датчика на стороне процессинга. Мне просто оч нужно чтобы помимо всего прочего ардуина общалась с этим компом по фирмате. А программулину на serial уже давно испытал. немного разберусь скину код для общего пользования

Единственный вопрос теперь как вот эти вещи PINC & _BV(DHT11_PIN, DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN); в PinMode и т.д. переделать

 

//Arduino Sample code
#define DHT11_PIN 0 // ADC0
byte read_dht11_dat()
{
byte i = 0;
byte result=0;
for(i=0; i< 8; i++)
{
while(!(PINC & _BV(DHT11_PIN))); // wait for 50us
delayMicroseconds(30);
if(PINC & _BV(DHT11_PIN))
result |=(1<<(7-i));
while((PINC & _BV(DHT11_PIN))); // wait '1' finish
}
return result;
}
void setup()
{
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
Serial.begin(9600);
Serial.println("Ready");
}
void loop()
{
byte dht11_dat[5];
byte dht11_in;
byte i;// start condition
// 1. pull-down i/o pin from 18ms
PORTC &= ~_BV(DHT11_PIN);
delay(18);
PORTC |= _BV(DHT11_PIN);
delayMicroseconds(40);
DDRC &= ~_BV(DHT11_PIN);
delayMicroseconds(40);
dht11_in = PINC & _BV(DHT11_PIN);
if(dht11_in)
{
Serial.println("dht11 start condition 1 not met");
return;
}
delayMicroseconds(80);
dht11_in = PINC & _BV(DHT11_PIN);
if(!dht11_in)
{
Serial.println("dht11 start condition 2 not met");
return;
}
delayMicroseconds(80);// now ready for data reception
for (i=0; i<5; i++)
dht11_dat[i] = read_dht11_dat();
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];// check
check_sum
if(dht11_dat[4]!= dht11_check_sum)
{
Serial.println("DHT11 checksum error");
}
Serial.print("Current humdity = ");
Serial.print(dht11_dat[0], DEC);
Serial.print(".");
Serial.print(dht11_dat[1], DEC);
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(dht11_dat[2], DEC);
Serial.print(".");
Serial.print(dht11_dat[3], DEC);
Serial.println("C ");
delay(2000);
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

 >Мне просто оч нужно чтобы помимо всего прочего ардуина общалась с этим компом по фирмате

Честно говоря не ковырялся с фирматой. Всегда, на самом деле, как-то проще было свой протокол замутить (мне кажется фирмата нужно только когда заранее не знаешь "что будешь гонять" и "какое там железо будет"), но что-то мне думаетеся, что можно попробовать "подружить" фирмату и "свой serial". Заставить их работать "паралельно".

Для "своего" придумать какой-то маркер типа "это твои данные", и свои данные формировать таким образом что-бы фирмата воспринимала их как "шум/мусор" и игнорировала.

leshak
Offline
Зарегистрирован: 29.09.2011

 А можно попробовать, все-таки "впихнутся в фирмату".

Вот описание протокола http://firmata.org/wiki/Protocol

Так как он "базируется на midi", то у него есть возможности для расширения что-бы посылать кастомные команды и данные (Sysex Message и т.п.)

Попытатся добавить "поддержку вашего датчика", так же как они добавили поддержку i2c и servo

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

 Пока для меня это оч сложно

leshak
Offline
Зарегистрирован: 29.09.2011

Nikelbak пишет:

Единственный вопрос теперь как вот эти вещи PINC & _BV(DHT11_PIN, DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN); в PinMode и т.д. переделать

Что-бы "понять это".

Нужно прочитать http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry

И http://arduino.cc/en/Reference/HomePage раздел "Bitwise Operators"

Ну и поискать как определен макрос _BV

подозреваю что это _BV(No) это эквивалент 1<<No  (вообщем возвращает байт с битом No установленным в 1)

 

Это далеко не единсвенная проблема :) Учитывая что при чтении датчика у вас есть задержки в микросекунды - это будет трудно выдержать, если логика "на стороне компа". Если размер это задержки "важен", то хош, не хоч, а прийдется ее передвигать "поближе к железу", то есть все-таки работать с датчиком из самого скетча. А компу слать уже обработанные данные. Через сериал, или как-то извернутся и впихарится в Firmata сообщения.

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

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

Вот пока надыбал скетч в котором исключено управление портами через регистры. Я все же пока попробую переделать этот код под Processing и попытаюсь устранить задержку с помощью delay.

#define dht11_pin 2 //

  
byte read_dht11_dat()
{
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++)
  {
    while (!digitalRead(dht11_pin));
    delayMicroseconds(30);
    if (digitalRead(dht11_pin) != 0 )
      bitSet(result, 7-i);
    while (digitalRead(dht11_pin));
  }
  return result;
}
  
  
void setup()
{
  pinMode(dht11_pin, OUTPUT);
  digitalWrite(dht11_pin, HIGH);
  Serial.begin(9600);
  Serial.println("Ready");
}
      
void loop()    
{
  byte dht11_dat[5];   
  byte dht11_in;
  byte i;// start condition
       
  digitalWrite(dht11_pin, LOW);
  delay(18);
  digitalWrite(dht11_pin, HIGH);
  delayMicroseconds(1);
  pinMode(dht11_pin, INPUT);
  delayMicroseconds(40);     
    
  if (digitalRead(dht11_pin))
  {
    Serial.println("dht11 start condition 1 not met"); // wait for DHT response signal: LOW
    delay(1000);
    return;
  }
  delayMicroseconds(80);
  if (!digitalRead(dht11_pin))
  {
    Serial.println("dht11 start condition 2 not met");  //wair for second response signal:HIGH
    return;
  }
    
  delayMicroseconds(80);// now ready for data reception
  for (i=0; i<5; i++)
  {  dht11_dat[i] = read_dht11_dat();}  //recieved 40 bits data. Details are described in datasheet
    
  pinMode(dht11_pin, OUTPUT);
  digitalWrite(dht11_pin, HIGH);
  byte dht11_check_sum = dht11_dat[0]+dht11_dat[2];// check check_sum
  if(dht11_dat[4]!= dht11_check_sum)
  {
    Serial.println("DHT11 checksum error");
  }
  Serial.print("Current humdity = ");
  Serial.print(dht11_dat[0], DEC);
  Serial.print("%  ");
  Serial.print("temperature = ");
  Serial.print(dht11_dat[2], DEC);
  Serial.println("C  ");
  delay(2000); //fresh time
}

 

rogabob
Offline
Зарегистрирован: 25.09.2015

Так вы сделалали или нет? 

Очень интересуюсь даной тиматикой.