Ver Fonte

:tada: first commit, working thermometer

Felix Bytow há 1 semana atrás
commit
8cf0eaf560
11 ficheiros alterados com 271 adições e 0 exclusões
  1. 24 0
      analog_sensor.cpp
  2. 21 0
      analog_sensor.h
  3. 27 0
      application.cpp
  4. 52 0
      application.h
  5. 17 0
      arduino-uno-thermometer.ino
  6. 13 0
      heart_beat.cpp
  7. 16 0
      heart_beat.h
  8. 23 0
      led.cpp
  9. 27 0
      led.h
  10. 15 0
      node.cpp
  11. 36 0
      node.h

+ 24 - 0
analog_sensor.cpp

@@ -0,0 +1,24 @@
+#include "analog_sensor.h"
+
+#include <Arduino.h>
+
+#include <limits.h>
+
+AnalogSensor::AnalogSensor(uint8_t const pin)
+  : pin_{ pin }, value_{ INT_MIN }, previousValue_{ INT_MIN } {}
+
+void AnalogSensor::init() noexcept {
+}
+
+void AnalogSensor::update(unsigned long deltaMillis) noexcept {
+  previousValue_ = value_;
+  value_ = analogRead(pin_);
+}
+
+bool AnalogSensor::hasValueChanged() const noexcept {
+  return previousValue_ != value_;
+}
+
+int AnalogSensor::getValue() const noexcept {
+  return value_;
+}

+ 21 - 0
analog_sensor.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "node.h"
+
+// uint8_t
+#include <stdint.h>
+
+class AnalogSensor final : public Node {
+public:
+  explicit AnalogSensor(uint8_t pin) noexcept;
+
+  void init() noexcept override;
+  void update(unsigned long deltaMillis) noexcept override;
+
+  bool hasValueChanged() const noexcept;
+  int getValue() const noexcept;
+
+private:
+  uint8_t pin_;
+  int value_, previousValue_;
+};

+ 27 - 0
application.cpp

@@ -0,0 +1,27 @@
+#include "application.h"
+
+#include <WString.h>
+
+void Application::init() noexcept {
+  AbstractNode::init();
+  lcd_.begin(16, 2);
+  lcd_.clear();
+}
+
+void Application::update(unsigned long const deltaMillis) noexcept {
+  AbstractNode::update(deltaMillis);
+
+  updateDisplay_ += deltaMillis;
+
+  auto const& hs = children_.getHeatSensor();
+  if (hs.hasValueChanged() && updateDisplay_ > 250ul) {
+    float const voltage = (hs.getValue() / 1024.0f) * 5.0f;
+    float const temperature = (voltage - 0.5f) * 100.0f;
+    lcd_.home();
+    lcd_.write("Temperature: ");
+    lcd_.setCursor(0, 1);
+    lcd_.write(String{temperature, 2}.c_str());
+    lcd_.write(" DC       ");
+    updateDisplay_ = 0ul;
+  }
+}

+ 52 - 0
application.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include "node.h"
+#include "heart_beat.h"
+#include "analog_sensor.h"
+
+// LED_BUILTIN, A0
+#include <pins_arduino.h>
+
+#include <LiquidCrystal.h>
+
+class Application final : public AbstractNode {
+public:
+  void init() noexcept override;
+
+  void update(unsigned long deltaMillis) noexcept override;
+
+protected:
+  NodeList& getChildren() noexcept override {
+    return children_;
+  }
+
+private:
+  LiquidCrystal lcd_{ 12, 11, 5, 4, 3, 2 };
+  unsigned long updateDisplay_ = 0ul;
+
+  class Children final : public NodeList {
+  public:
+    AnalogSensor const& getHeatSensor() const noexcept {
+      return heatSensor_;
+    }
+
+    Node* get(size_t const index) noexcept override {
+      switch (index) {
+        case 0:
+          return &heartBeat_;
+        case 1:
+          return &heatSensor_;
+        default:
+          return nullptr;
+      }
+    }
+
+    size_t size() const noexcept override {
+      return 2;
+    }
+
+  private:
+    HeartBeat heartBeat_{ LED_BUILTIN };
+    AnalogSensor heatSensor_{ A0 };
+  } children_;
+};

+ 17 - 0
arduino-uno-thermometer.ino

@@ -0,0 +1,17 @@
+#include "application.h"
+
+static unsigned long previousMillis;
+
+static Application application{};
+
+void setup() {
+  application.init();
+  previousMillis = millis();
+}
+
+void loop() {
+  unsigned long const currentMillis = millis();
+  unsigned long const deltaMillis = currentMillis - previousMillis;
+  previousMillis = currentMillis;
+  application.update(deltaMillis);
+}

+ 13 - 0
heart_beat.cpp

@@ -0,0 +1,13 @@
+#include "heart_beat.h"
+
+HeartBeat::HeartBeat(uint8_t const pin) noexcept
+  : led_{ pin }, t_{ 0ul } {}
+
+void HeartBeat::init() noexcept {
+  led_.init();
+}
+
+void HeartBeat::update(unsigned long deltaMillis) noexcept {
+  t_ = (t_ + deltaMillis) % 2000ul;
+  led_.setState(t_ < 1000ul ? LS_On : LS_Off);
+}

+ 16 - 0
heart_beat.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include "node.h"
+#include "led.h"
+
+class HeartBeat final : public Node {
+public:
+  explicit HeartBeat(uint8_t pin) noexcept;
+
+  void init() noexcept override;
+  void update(unsigned long deltaMillis) noexcept override;
+
+private:
+  Led led_;
+  unsigned long t_;
+};

+ 23 - 0
led.cpp

@@ -0,0 +1,23 @@
+#include "led.h"
+
+#include <Arduino.h>
+
+Led::Led(uint8_t const pin)
+  : pin_{ pin } {
+}
+
+void Led::init() noexcept {
+  pinMode(pin_, OUTPUT);
+}
+
+void Led::setState(LedState const state) noexcept {
+  digitalWrite(pin_, static_cast<uint8_t>(state));
+}
+
+LedState Led::getState() const noexcept {
+  return static_cast<LedState>(digitalRead(pin_));
+}
+
+void Led::toggleState() noexcept {
+  return setState(~getState());
+}

+ 27 - 0
led.h

@@ -0,0 +1,27 @@
+#pragma once
+
+// uint8_t
+#include <stdint.h>
+
+enum LedState {
+  LS_Off = 0,
+  LS_On = 1,
+};
+
+constexpr LedState operator~(LedState const state) noexcept {
+  return state == LS_On ? LS_Off : LS_On;
+}
+
+class Led final {
+public:
+  explicit Led(uint8_t pin);
+
+  void init() noexcept;
+
+  void setState(LedState state) noexcept;
+  LedState getState() const noexcept;
+  void toggleState() noexcept;
+
+private:
+  uint8_t pin_;
+};

+ 15 - 0
node.cpp

@@ -0,0 +1,15 @@
+#include "node.h"
+
+void AbstractNode::init() noexcept {
+  NodeList& children = getChildren();
+  for (size_t n = children.size(); n--;) {
+    children.get(n)->init();
+  }
+}
+
+void AbstractNode::update(unsigned long deltaMillis) noexcept {
+  NodeList& children = getChildren();
+  for (size_t n = children.size(); n--;) {
+    children.get(n)->update(deltaMillis);
+  }
+}

+ 36 - 0
node.h

@@ -0,0 +1,36 @@
+#pragma once
+
+// size_t
+#include <stddef.h>
+
+class Node {
+public:
+  virtual ~Node() noexcept = default;
+
+  virtual void init() noexcept = 0;
+  virtual void update(unsigned long deltaMillis);
+};
+
+class NodeList {
+public:
+  virtual ~NodeList() noexcept = default;
+
+  virtual size_t size() const noexcept = 0;
+  
+  virtual Node* get(size_t index) noexcept {
+    return nullptr;
+  }
+
+  virtual Node const* get(size_t index) const noexcept {
+    return const_cast<NodeList*>(this)->get(index);
+  }
+};
+
+class AbstractNode : public Node {
+public:
+  void init() noexcept override;
+  void update(unsigned long deltaMillis) noexcept override;
+
+protected:
+  virtual NodeList& getChildren() noexcept = 0;
+};