Use custom ADC interface using AVR flags
This commit is contained in:
+7
-4
@@ -27,9 +27,10 @@ CXXFLAGS = $(CFLAGS) -fno-exceptions -fpermissive -std=gnu++11
|
||||
LDFLAGS = -Wall -Os -mmcu=$(MCU) -Wl,--gc-sections
|
||||
LIBS = -lm
|
||||
|
||||
SRCS_CPP = main.cpp moisture.cpp
|
||||
HDRS = moisture.h config.h
|
||||
OBJS = $(addprefix $(OBJ_DIR)/, $(SRCS_CPP:.cpp=.o))
|
||||
SRCS_C = adc.c moisture.c main.c
|
||||
#SRCS_CPP = main.cpp
|
||||
HDRS = moisture.h config.h adc.h
|
||||
OBJS = $(addprefix $(OBJ_DIR)/, $(SRCS_CPP:.cpp=.o) $(SRCS_C:.c=.o))
|
||||
|
||||
CORE_C_SRCS = \
|
||||
wiring.c \
|
||||
@@ -44,7 +45,6 @@ CORE_CPP_SRCS = \
|
||||
Stream.cpp \
|
||||
HardwareSerial.cpp \
|
||||
HardwareSerial0.cpp \
|
||||
main.cpp
|
||||
|
||||
CORE_SRCS = $(addprefix $(ARDUINO_CORE_PATH)/, $(CORE_C_SRCS) $(CORE_CPP_SRCS))
|
||||
CORE_OBJS = $(patsubst $(ARDUINO_CORE_PATH)/%.c,$(CORE_DIR)/%.o,$(filter %.c,$(CORE_SRCS))) \
|
||||
@@ -66,6 +66,9 @@ $(ELF_TARGET): $(OBJS) $(CORE_LIB)
|
||||
$(CORE_LIB): $(CORE_OBJS)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJ_DIR)/%.o: %.cpp $(HDRS) Makefile
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <stdint.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
void adcInit(void) {
|
||||
// Set reference voltage to AVcc (REFS0 = 1, REFS1 = 0)
|
||||
ADMUX = (1 << REFS0);
|
||||
|
||||
// Enable ADC and set prescaler to 128 (for 16 MHz clock, gives 125 kHz ADC clock)
|
||||
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
|
||||
}
|
||||
|
||||
uint16_t adcRead(uint8_t channel) {
|
||||
// Select ADC pin (A0-A7) by setting MUX bits in ADMUX
|
||||
// Pins A6 and A7 would make an 8 sensor array possible (for large vases).
|
||||
// Achievable only when using the 328p as a DIP, through port C (PC6, PC7)
|
||||
ADMUX = (ADMUX & 0xF8) | (channel & 0x07);
|
||||
|
||||
// Start conversion
|
||||
ADCSRA |= (1 << ADSC);
|
||||
|
||||
// Wait for conversion to complete (ADSC becomes '0' when done)
|
||||
while (ADCSRA & (1 << ADSC));
|
||||
|
||||
// Read ADC (reading order: ADCL --> ADCH)
|
||||
return ADC;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef ADC_H
|
||||
#define ADC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
void adcInit(void);
|
||||
uint16_t adcRead(uint8_t channel);
|
||||
|
||||
#endif
|
||||
+13
-2
@@ -1,7 +1,18 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define MOISTURE_SENSOR_A0 A0
|
||||
#define SENSOR_READINGS 3
|
||||
#define MOISTURE_SENSOR_A0 PC0
|
||||
#define MOISTURE_SENSOR_A1 PC1
|
||||
#define MOISTURE_SENSOR_A2 PC2
|
||||
#define MOISTURE_SENSOR_A3 PC3
|
||||
#define MOISTURE_SENSOR_A4 PC4
|
||||
#define MOISTURE_SENSOR_A5 PC5
|
||||
// NOTE: PC6 PC7 are not accessible by default on Arduino Uno R3
|
||||
// You need to use the ATMega328p on a custom PCB and use pins 1 and 2
|
||||
#define MOISTURE_SENSOR_A6 PC6
|
||||
#define MOISTURE_SENSOR_A7 PC7
|
||||
|
||||
|
||||
#define SENSOR_READINGS 5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/sleep.h>
|
||||
@@ -26,17 +25,19 @@ void enterSleep(void) {
|
||||
}
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
initMoistureSensor();
|
||||
watchdogs();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
setup();
|
||||
|
||||
while(true) {
|
||||
|
||||
if (readSensors) {
|
||||
int16_t result = readMoisture();
|
||||
if (result != -1) {
|
||||
Serial.println(result);
|
||||
//Serial.println(result);
|
||||
readSensors = false;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "moisture.h"
|
||||
#include "config.h"
|
||||
#include "adc.h"
|
||||
|
||||
static int16_t moistureReadingSum = 0;
|
||||
static int8_t moistureReadingCount = 0;
|
||||
@@ -12,7 +12,8 @@ static int8_t moistureReadingCount = 0;
|
||||
volatile bool readSensors = false;
|
||||
|
||||
void initMoistureSensor(void) {
|
||||
pinMode(MOISTURE_SENSOR_A0, INPUT);
|
||||
DDRC &= ~(1 << MOISTURE_SENSOR_A0); // set as input
|
||||
PORTC &= ~(1 << MOISTURE_SENSOR_A0); //disable pullup
|
||||
}
|
||||
|
||||
void triggerSensorRead(void) {
|
||||
@@ -23,13 +24,13 @@ int16_t readMoisture(void) {
|
||||
if (!readSensors)
|
||||
return -1;
|
||||
|
||||
moistureReadingSum += analogRead(MOISTURE_SENSOR_A0);
|
||||
adcInit();
|
||||
moistureReadingSum += adcRead(MOISTURE_SENSOR_A0);
|
||||
moistureReadingCount++;
|
||||
|
||||
//TODO: implement variance check (if over a certain variance discard measurements for this cicle)
|
||||
if (moistureReadingCount >= SENSOR_READINGS) {
|
||||
int16_t average = moistureReadingSum / SENSOR_READINGS;
|
||||
//Serial.println(average);
|
||||
moistureReadingSum = 0;
|
||||
moistureReadingCount = 0;
|
||||
readSensors = false;
|
||||
Reference in New Issue
Block a user