Plant Watering Sensor
Hardware Namespace Reference

This module is the interface to the Hardware via GPIO, ADC and Counter. More...

Enumerations

enum  LedState : uint8_t { LED_Off = 0x00u, LED_Green = 0x01u, LED_Red = 0x02u }
 The state of the current display (LED). More...
 

Functions

void setup ()
 Setup the MCU hardware to the initial values. More...
 
void setLedState (LedState ledState)
 Enable or disable the status LEDs. More...
 
void sendDoneSignal ()
 Send the done signal. More...
 
bool isButtonPressed ()
 Get the status of the button. More...
 
uint16_t getVoltageValue ()
 Read the current voltage value. More...
 
void shutdownVoltageMeasurement ()
 Shutdown voltage measurement to save power. More...
 
uint8_t getOscillatorFrequency ()
 Try to determine the frequency. More...
 
void shutdownOscillatorCounter ()
 Shutdown the counter to save power. More...
 

Detailed Description

This module is the interface to the Hardware via GPIO, ADC and Counter.

Enumeration Type Documentation

◆ LedState

enum Hardware::LedState : uint8_t

The state of the current display (LED).

Enumerator
LED_Off 

The LED is off.

LED_Green 

The green LED is on.

LED_Red 

The red LED is on.

Definition at line 34 of file Hardware.h.

34  : uint8_t {
35  LED_Off = 0x00u,
36  LED_Green = 0x01u,
37  LED_Red = 0x02u,
38 };
The green LED is on.
Definition: Hardware.h:36
The LED is off.
Definition: Hardware.h:35
The red LED is on.
Definition: Hardware.h:37

Function Documentation

◆ getOscillatorFrequency()

uint8_t Hardware::getOscillatorFrequency ( )

Try to determine the frequency.

I assume the frequency from the oscillator will be somewhere in a kHz range. The maximum frequency of the oscillator is somewhere around 140kHz the lowest (100% water) around 40kHz. Measuring the number of rising edges for ~1ms should generate a usable value.

If no signal is received, 0x00 is returned. If the counter overflows, 0xff is returned. (This should not happen).

Returns
The approximate oscillator frequency in kHz.

Definition at line 136 of file Hardware.cpp.

137 {
138  // Select external clock source, T0/Pin 7 to enable the counter.
139  TCCR0B = (_BV(CS00)|_BV(CS01)|_BV(CS02));
140  // Reset the counter.
141  TCNT0 = 0;
142  // Clear the overflow flag.
143  TIFR0 = _BV(TOV0);
144  // Wait ~1ms for the result.
145  Tool::delayMs(1);
146  // Read the result.
147  uint8_t result = TCNT0;
148  // Check the overflow flag.
149  if ((TIFR0 & _BV(TOV0)) != 0) {
150  result = 0xff;
151  }
152  return result;
153 }
void delayMs(uint16_t delay)
Wait approximate the given number of milliseconds.
Definition: Tool.cpp:31

◆ getVoltageValue()

uint16_t Hardware::getVoltageValue ( )

Read the current voltage value.

Returns
The current voltage value. ~23 per 0.1V.

Definition at line 105 of file Hardware.cpp.

106 {
107  // Collect a number of samples and get the average out of them.
108  uint16_t values = 0u;
109  const uint8_t sampleCount = 32u;
110  for (uint8_t i = 0; i < sampleCount; ++i) {
111  // Start the conversion.
112  ADCSRA |= _BV(ADSC);
113  // Wait for the conversion to finish.
114  while ((ADCSRA & _BV(ADSC)) != 0) {
115  _NOP();
116  }
117  // Read the value.
118  uint16_t value = ADCL;
119  value |= ((uint16_t)(ADCH) << 8);
120  // Add it up to get the average.
121  values += value;
122  }
123  // Return the average of all samples.
124  return (values / sampleCount);
125 }

◆ isButtonPressed()

bool Hardware::isButtonPressed ( )

Get the status of the button.

Returns
true if the push button is pressed.

Definition at line 99 of file Hardware.cpp.

100 {
101  return ((PINB & _BV(PINB3)) != 0);
102 }

◆ sendDoneSignal()

void Hardware::sendDoneSignal ( )

Send the done signal.

Definition at line 89 of file Hardware.cpp.

90 {
91  // Just set the done line to high for 10ms.
92  PORTB |= _BV(DDB0);
93  Tool::delayMs(10);
94  PORTB &= ~_BV(DDB0);
95  Tool::delayMs(100);
96 }
void delayMs(uint16_t delay)
Wait approximate the given number of milliseconds.
Definition: Tool.cpp:31

◆ setLedState()

void Hardware::setLedState ( LedState  ledState)

Enable or disable the status LEDs.

Parameters
ledStateThe LED state.

Definition at line 69 of file Hardware.cpp.

70 {
71  switch (ledState) {
72  case LED_Off:
73  default: // Set PB0 to Hi-Z;
74  DDRB &= (~_BV(DDB1));
75  PORTB &= (~_BV(PORTB1));
76  break;
77  case LED_Green: // Set PB0 to HIGH.
78  DDRB |= _BV(DDB1);
79  PORTB |= _BV(PORTB1);
80  break;
81  case LED_Red: // Set PB0 to LOW.
82  DDRB |= _BV(DDB1);
83  PORTB &= (~_BV(PORTB1));
84  break;
85  }
86 }
The green LED is on.
Definition: Hardware.h:36
The LED is off.
Definition: Hardware.h:35
The red LED is on.
Definition: Hardware.h:37

◆ setup()

void Hardware::setup ( )

Setup the MCU hardware to the initial values.

Definition at line 35 of file Hardware.cpp.

36 {
37  // Set the pre-scaler frequency to 2.4MHz.
38  CLKPR = _BV(CLKPCE); // First set the CE bit.
39  CLKPR = _BV(CLKPS1); // ...then set the clock frequency.
40 
41  // Setup PORTB:
42  // - PB0/Pin 5 as output (done signal).
43  // - PB1/Pin 6 keep tristate Hi-Z for the display (LED).
44  // - PB2/Pin 7 as input (oscillator) used for counter.
45  // - PB3/Pin 2 as input (button).
46  DDRB = _BV(DDB0);
47  // Make sure all outputs are low.
48  PORTB = 0;
49 
50  // Setup the ADC for PB4/Pin 3
51  // - Use the internal 1.1V source.
52  // - Left align the result.
53  // - Use PB4/Pin 3 as input.
54  ADMUX = (_BV(REFS0)|_BV(MUX1));
55  // - Enable the ADC (to allow enough time to stabilize)
56  // - Prescaler to 128, to get 75kHz which should be get an accurate result.
57  ADCSRA = (_BV(ADEN)|_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0));
58  // - Disable the digital in on for PB0, PB1, PB4 to reduce power usage.
59  DIDR0 = (_BV(AIN0D)|_BV(AIN1D)|_BV(ADC2D));
60 
61  // Setup the counter.
62  // - no compare match, no PWM, no compare output.
63  TCCR0A = 0;
64  // - No Interrupt
65  TIMSK0 = 0;
66 }

◆ shutdownOscillatorCounter()

void Hardware::shutdownOscillatorCounter ( )

Shutdown the counter to save power.

After calling this method, the getOscillatorFrequency() call will not work anymore.

Definition at line 156 of file Hardware.cpp.

157 {
158  // Stop the counter and shutdown the module to save power.
159  TCCR0B = 0;
160  PRR |= _BV(PRTIM0);
161 }

◆ shutdownVoltageMeasurement()

void Hardware::shutdownVoltageMeasurement ( )

Shutdown voltage measurement to save power.

Definition at line 128 of file Hardware.cpp.

129 {
130  // Disable the ADC to save power.
131  ADCSRA &= ~_BV(ADEN); // Disable the ADC
132  PRR |= _BV(PRADC); // Shutdown the ADC to save power.
133 }