diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-02-14 17:34:30 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-02-14 17:34:30 +0300 |
commit | 9d8c0909cb178be570b94b1bd53d91d8b90dd12c (patch) | |
tree | de1df192921bee8b56c07f425d12f321884a41d2 /src/Heating | |
parent | 3a5f87f516d526f86bf3535e2627784852c1b05f (diff) |
Fixed DHT sensors on Duet 3 Mini
Diffstat (limited to 'src/Heating')
-rw-r--r-- | src/Heating/Sensors/DhtSensor.cpp | 58 | ||||
-rw-r--r-- | src/Heating/Sensors/DhtSensor.h | 8 |
2 files changed, 60 insertions, 6 deletions
diff --git a/src/Heating/Sensors/DhtSensor.cpp b/src/Heating/Sensors/DhtSensor.cpp index 283d56c9..ca89796b 100644 --- a/src/Heating/Sensors/DhtSensor.cpp +++ b/src/Heating/Sensors/DhtSensor.cpp @@ -26,8 +26,8 @@ void DhtDataTransition(CallbackParameter cp) noexcept } // Class DhtTemperatureSensor members -DhtTemperatureSensor::DhtTemperatureSensor(unsigned int sensorNum, DhtSensorType type) noexcept - : SensorWithPort(sensorNum, "DHT-temperature"), type(type), lastReadTime(0) +DhtTemperatureSensor::DhtTemperatureSensor(unsigned int sensorNum, DhtSensorType t) noexcept + : SensorWithPort(sensorNum, "DHT-temperature"), type(t), lastReadTime(0) { } @@ -48,10 +48,39 @@ const char *DhtTemperatureSensor::GetShortSensorType() const noexcept GCodeResult DhtTemperatureSensor::Configure(GCodeBuffer& gb, const StringRef& reply, bool& changed) { - if (!ConfigurePort(gb, reply, PinAccess::write0, changed)) +#if SAME5x + // SAME5x needs two ports because the output ports don't support interrupts + if (gb.Seen('P')) + { + IoPort* const portAddrs[] = { &port, &interruptPort }; + PinAccess const accessModes[] = { PinAccess::write1, PinAccess::read }; + switch (IoPort::AssignPorts(gb, reply, PinUsedBy::sensor, 2, portAddrs, accessModes)) + { + case 2: + break; // success + + case 0: + return GCodeResult::error; // error message has already been written to 'reply' + + default: + reply.copy("on this board, this sensor type needs one output and one input port"); + return GCodeResult::error; + } + + numPulses = ARRAY_SIZE(pulses); // tell the ISR not to collect data yet + if (!interruptPort.AttachInterrupt(DhtDataTransition, InterruptMode::change, this)) + { + reply.copy("failed to attach interrupt to port "); + interruptPort.AppendPinName(reply); + return GCodeResult::error; + } + } +#else + if (!ConfigurePort(gb, reply, PinAccess::write1, changed)) { return GCodeResult::error; } +#endif TryConfigureSensorName(gb, changed); @@ -65,7 +94,19 @@ GCodeResult DhtTemperatureSensor::Configure(GCodeBuffer& gb, const StringRef& re if (!changed) { +#if SAME5x + reply.printf("Sensor %u", GetSensorNumber()); + if (GetSensorName() != nullptr) + { + reply.catf(" (%s)", GetSensorName()); + } + reply.catf(" type %s using pins ", GetSensorType()); + const IoPort* const portAddrs[] = { &port, &interruptPort }; + IoPort::AppendPinNames(reply, 2, portAddrs); + reply.catf(", reading %.1f, last error: %s", (double)GetStoredReading(), TemperatureErrorString(GetLastError())); +#else CopyBasicDetails(reply); +#endif const char *sensorTypeString; switch (type) @@ -138,6 +179,13 @@ bool DhtTemperatureSensor::PollInTask() noexcept void DhtTemperatureSensor::TakeReading() noexcept { + const IoPort& irqPort = +#if SAME5x + interruptPort; +#else + port; +#endif + // Send the start bit. This must be at least 18ms for the DHT11, 0.8ms for the DHT21, and 1ms long for the DHT22. port.SetMode(PinAccess::write0); delay(20); @@ -156,7 +204,7 @@ void DhtTemperatureSensor::TakeReading() noexcept // It appears that switching the pin to an output disables the interrupt, so we need to call attachInterrupt here // We are likely to get an immediate interrupt at this point corresponding to the low-to-high transition. We must ignore this. - port.AttachInterrupt(DhtDataTransition, InterruptMode::change, this); + irqPort.AttachInterrupt(DhtDataTransition, InterruptMode::change, this); delayMicroseconds(2); // give the interrupt time to occur lastPulseTime = 0; numPulses = 0; // tell the ISR to collect data @@ -167,7 +215,7 @@ void DhtTemperatureSensor::TakeReading() noexcept // So we just delay for long enough for the data to have been sent. It takes typically 4 to 5ms. delay(MaximumReadTime); - port.DetachInterrupt(); + irqPort.DetachInterrupt(); // Attempt to convert the signal into temp+RH values float t; diff --git a/src/Heating/Sensors/DhtSensor.h b/src/Heating/Sensors/DhtSensor.h index 12a3c64b..91855438 100644 --- a/src/Heating/Sensors/DhtSensor.h +++ b/src/Heating/Sensors/DhtSensor.h @@ -27,7 +27,7 @@ enum class DhtSensorType class DhtTemperatureSensor : public SensorWithPort { public: - DhtTemperatureSensor(unsigned int sensorNum, DhtSensorType type) noexcept; + DhtTemperatureSensor(unsigned int sensorNum, DhtSensorType t) noexcept; ~DhtTemperatureSensor() noexcept; GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& changed) override THROWS(GCodeException); @@ -46,6 +46,12 @@ public: static constexpr const char *TypeNameDht22 = "dht22"; private: + +#if SAME5x + // On the SAME5c we need a separate port to get the interrupt, because the output ports don't support interrupts + IoPort interruptPort; +#endif + DhtSensorType type; float lastHumidity; |