Example #1
0
File: DHT.cpp Project: acsnow6/Cosa
/*
 * The interrupt handler, enabled after the request pulse, and on
 * falling (low to high) transition. This allows lower interrupt
 * frequency than on change mode (which would be required for pin
 * change interrupts. First pulse is the device response and a
 * one(1) bit is encoded as a long pulse (54 + 80 = 134 us), a
 * zero(0) bit as a short pulse (54 + 24 = 78 us). Sequence ends
 * with a low pulse (54 us) which allows falling/rising detection.
 */
void
DHT::on_interrupt(uint16_t arg)
{
  UNUSED(arg);

  // Calculate the pulse width and check against thresholds
  uint16_t stop = RTT::micros();
  uint16_t us = (stop - m_start);
  bool valid = false;

  // Check the initial response pulse
  if (m_state == RESPONSE) {
    if (us < BIT_THRESHOLD) goto exception;
    m_state = SAMPLING;
    m_start = stop;
    m_bits = 0;
    m_ix = 0;
    return;
  }

  // Sanity check the pulse length
  if (us < LOW_THRESHOLD || us > HIGH_THRESHOLD) goto exception;
  m_start = stop;

  // Sample was valid, collect bit and check for more
  m_value = (m_value << 1) + (us > BIT_THRESHOLD);
  m_bits += 1;
  if (m_bits != CHARBITS) return;

  // Next byte ready
  m_data.as_byte[m_ix++] = m_value;
  m_bits = 0;
  valid = (m_ix == DATA_MAX);
  if (valid) goto completed;
  return;

  // Invalid sample reject sequence
 exception:
  m_ix = 0;

  // Sequence completed
 completed:
  m_state = COMPLETED;
  disable();
  if (valid) adjust_data();
  on_sample_completed(valid);
}
Example #2
0
void 
DHT::on_event(uint8_t type, uint16_t value)
{
  UNUSED(type);
  UNUSED(value);
  switch (m_state) {

  case IDLE: 
    // Issue a request; pull down for more than 18 ms
    m_state = REQUEST;
    set_mode(OUTPUT_MODE);
    clear();
    Watchdog::attach(this, 32);
    break;

  case REQUEST: 
    // Request pulse completed; pull up for 40 us and collect
    // data as a sequence of on rising mode interrupts
    m_state = RESPONSE;
    m_start = 0;
    detach();
    set();
    set_mode(INPUT_MODE);
    DELAY(40);
    enable();
    break;

  case COMPLETED:
    // Data reading was completed; validate data and check sum
    // Wait before issueing the next request
    uint8_t invalid = 1;
    if (m_ix == DATA_MAX) {
      uint8_t sum = 0;
      for (uint8_t i = 0; i < DATA_LAST; i++) 
	sum += m_data.as_byte[i];
      if (sum == m_data.chksum) {
	invalid = 0;
	adjust_data();
      }
      on_sample_completed();
    }
    m_errors += invalid;
    m_state = IDLE;
    Watchdog::attach(this, m_period);
    break;
  }
}
Example #3
0
bool
DHT::sample_await()
{
  if (m_period != 0) return (true);
  uint32_t start = RTC::millis();
  while (m_state != COMPLETED && RTC::since(start) < MIN_PERIOD) 
    yield();
  if (m_state != COMPLETED) return (false);

  // Data reading was completed; validate data and check sum
  m_state = INIT;
  if (m_ix != DATA_MAX) return (false);
  uint8_t sum = 0;
  for (uint8_t i = 0; i < DATA_LAST; i++) 
    sum += m_data.as_byte[i];
  if (sum != m_data.chksum) return (false);
  adjust_data();
  return (true);
}
Example #4
0
static float read_sample(struct sr_channel *ch)
{
	struct channel_priv *chp;
	char buf[16];
	ssize_t len;
	int fd;

	chp = ch->priv;
	fd = chp->fd;

	lseek(fd, 0, SEEK_SET);

	len = read(fd, buf, sizeof(buf));
	if (len < 0) {
		sr_err("Error reading from channel %s (hwmon: %d): %s",
			ch->name, chp->probe->hwmon_num, g_strerror(errno));
		ch->enabled = FALSE;
		return -1.0;
	}

	return adjust_data(strtol(buf, NULL, 10), chp->ch_type);
}