first commit
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
||||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"new": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
72
include/drivers/AccelerometerController.h
Normal file
72
include/drivers/AccelerometerController.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef ADXL345_CONTROLLER_H
|
||||||
|
#define ADXL345_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#define ADXL345_DEVID 0x00
|
||||||
|
#define ADXL345_THRESH_TAP 0x1D
|
||||||
|
#define ADXL345_OFSX 0x1E
|
||||||
|
#define ADXL345_OFSY 0x1F
|
||||||
|
#define ADXL345_OFSZ 0x20
|
||||||
|
#define ADXL345_DUR 0x21
|
||||||
|
#define ADXL345_LATENT 0x22
|
||||||
|
#define ADXL345_WINDOW 0x23
|
||||||
|
#define ADXL345_THRESH_ACT 0x24
|
||||||
|
#define ADXL345_THRESH_INACT 0x25
|
||||||
|
#define ADXL345_TIME_INACT 0x26
|
||||||
|
#define ADXL345_ACT_INACT_CTL 0x27
|
||||||
|
#define ADXL345_THRESH_FF 0x28
|
||||||
|
#define ADXL345_TIME_FF 0x29
|
||||||
|
#define ADXL345_TAP_AXES 0x2A
|
||||||
|
#define ADXL345_ACT_TAP_STATUS 0x2B
|
||||||
|
#define ADXL345_BW_RATE 0x2C
|
||||||
|
#define ADXL345_POWER_CTL 0x2D
|
||||||
|
#define ADXL345_INT_ENABLE 0x2E
|
||||||
|
#define ADXL345_INT_MAP 0x2F
|
||||||
|
#define ADXL345_INT_SOURCE 0x30
|
||||||
|
#define ADXL345_DATA_FORMAT 0x31
|
||||||
|
#define ADXL345_DATAX0 0x32
|
||||||
|
#define ADXL345_DATAX1 0x33
|
||||||
|
#define ADXL345_DATAY0 0x34
|
||||||
|
#define ADXL345_DATAY1 0x35
|
||||||
|
#define ADXL345_DATAZ0 0x36
|
||||||
|
#define ADXL345_DATAZ1 0x37
|
||||||
|
#define ADXL345_FIFO_CTL 0x38
|
||||||
|
#define ADXL345_FIFO_STATUS 0x39
|
||||||
|
|
||||||
|
#define DEFAULT_MIN_READ_INTERVAL 50
|
||||||
|
|
||||||
|
class ADXL345Controller {
|
||||||
|
private:
|
||||||
|
uint8_t _deviceAddress;
|
||||||
|
unsigned long _lastReadTime;
|
||||||
|
unsigned long _minReadInterval;
|
||||||
|
double _lastX;
|
||||||
|
double _lastY;
|
||||||
|
double _lastZ;
|
||||||
|
bool _lastReadSuccess;
|
||||||
|
|
||||||
|
void setRegister(uint8_t reg, uint8_t value);
|
||||||
|
uint8_t readRegister(uint8_t reg);
|
||||||
|
void readRegisters(uint8_t reg, uint8_t count, uint8_t *buffer);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADXL345Controller(uint8_t deviceAddress = 0x53);
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
|
||||||
|
bool read();
|
||||||
|
|
||||||
|
double getX();
|
||||||
|
double getY();
|
||||||
|
double getZ();
|
||||||
|
|
||||||
|
bool isLastReadSuccessful() const;
|
||||||
|
void setMinReadInterval(unsigned long interval);
|
||||||
|
void setRange(uint8_t range);
|
||||||
|
void setDataRate(uint8_t rate);
|
||||||
|
void setOffsets(int8_t xOffset, int8_t yOffset, int8_t zOffset);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
21
include/drivers/ButtonController.h
Normal file
21
include/drivers/ButtonController.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef BUTTON_CONTROLLER_H
|
||||||
|
#define BUTTON_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class ButtonController {
|
||||||
|
private:
|
||||||
|
const int _buttonPin;
|
||||||
|
unsigned long _lastDebounceTime;
|
||||||
|
unsigned long _debounceDelay;
|
||||||
|
bool _lastButtonState;
|
||||||
|
bool _buttonState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ButtonController(int buttonPin, unsigned long debounceDelay = 50);
|
||||||
|
bool wasOn();
|
||||||
|
void tick();
|
||||||
|
bool getState() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
27
include/drivers/DHTController.h
Normal file
27
include/drivers/DHTController.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef DHT_CONTROLLER_H
|
||||||
|
#define DHT_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <DHT.h>
|
||||||
|
|
||||||
|
class DHTController {
|
||||||
|
private:
|
||||||
|
DHT _dht;
|
||||||
|
unsigned long _lastReadTime;
|
||||||
|
unsigned long _minReadInterval;
|
||||||
|
float _lastTemperature;
|
||||||
|
float _lastHumidity;
|
||||||
|
bool _lastReadSuccess;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DHTController(uint8_t pin, uint8_t type = DHT11);
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
bool read();
|
||||||
|
float getTemperature();
|
||||||
|
float getHumidity();
|
||||||
|
bool isLastReadSuccessful() const;
|
||||||
|
void setMinReadInterval(unsigned long interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
37
include/drivers/DistanceSensorController.h
Normal file
37
include/drivers/DistanceSensorController.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef DISTANCE_SENSOR_CONTROLLER_H
|
||||||
|
#define DISTANCE_SENSOR_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define DEFAULT_MIN_READ_INTERVAL_DIST 100
|
||||||
|
#define DEFAULT_SAMPLES 3
|
||||||
|
#define MAX_DISTANCE 400
|
||||||
|
|
||||||
|
class DistanceSensorController {
|
||||||
|
private:
|
||||||
|
uint8_t _trigPin;
|
||||||
|
uint8_t _echoPin;
|
||||||
|
unsigned long _lastReadTime;
|
||||||
|
unsigned long _minReadInterval;
|
||||||
|
long _lastDistanceCm;
|
||||||
|
bool _lastReadSuccess;
|
||||||
|
uint8_t _numSamples;
|
||||||
|
unsigned long _timeout;
|
||||||
|
|
||||||
|
long microsecondsToCentimeters(long microseconds);
|
||||||
|
|
||||||
|
long takeMeasurement();
|
||||||
|
|
||||||
|
public:
|
||||||
|
DistanceSensorController(uint8_t trigPin, uint8_t echoPin);
|
||||||
|
void begin();
|
||||||
|
bool read();
|
||||||
|
long getDistanceCm();
|
||||||
|
long getDistanceInch();
|
||||||
|
bool isLastReadSuccessful() const;
|
||||||
|
void setMinReadInterval(unsigned long interval);
|
||||||
|
void setNumSamples(uint8_t samples);
|
||||||
|
void setTimeout(unsigned long timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
68
include/drivers/JoystickController.h
Normal file
68
include/drivers/JoystickController.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#ifndef JOYSTICK_H
|
||||||
|
#define JOYSTICK_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
enum JoystickDirection {
|
||||||
|
CENTER,
|
||||||
|
UP,
|
||||||
|
UP_RIGHT,
|
||||||
|
RIGHT,
|
||||||
|
DOWN_RIGHT,
|
||||||
|
DOWN,
|
||||||
|
DOWN_LEFT,
|
||||||
|
LEFT,
|
||||||
|
UP_LEFT
|
||||||
|
};
|
||||||
|
|
||||||
|
class JoystickController {
|
||||||
|
private:
|
||||||
|
uint8_t pinX;
|
||||||
|
uint8_t pinY;
|
||||||
|
uint8_t pinButton;
|
||||||
|
|
||||||
|
int centerX;
|
||||||
|
int centerY;
|
||||||
|
|
||||||
|
int rawX;
|
||||||
|
int rawY;
|
||||||
|
bool buttonState;
|
||||||
|
|
||||||
|
int deadzone;
|
||||||
|
int debounceDelay;
|
||||||
|
unsigned long lastDebounceTime;
|
||||||
|
|
||||||
|
int lastX;
|
||||||
|
int lastY;
|
||||||
|
bool lastButtonState;
|
||||||
|
|
||||||
|
void readRawValues();
|
||||||
|
|
||||||
|
static JoystickController* _instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JoystickController(uint8_t xPin, uint8_t yPin, uint8_t buttonPin = 255);
|
||||||
|
~JoystickController();
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
void calibrate();
|
||||||
|
void setDeadzone(int value);
|
||||||
|
void setDebounceDelay(int delayMs);
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
int getRawX();
|
||||||
|
int getRawY();
|
||||||
|
int getX();
|
||||||
|
int getY();
|
||||||
|
int getOffsetX();
|
||||||
|
int getOffsetY();
|
||||||
|
|
||||||
|
bool isPressed();
|
||||||
|
bool isCentered();
|
||||||
|
|
||||||
|
JoystickDirection getDirection();
|
||||||
|
String getDirectionString();
|
||||||
|
int getDistancePercent();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
34
include/drivers/LCDController.h
Normal file
34
include/drivers/LCDController.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef LCD_CONTROLLER_H
|
||||||
|
#define LCD_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <LiquidCrystal.h>
|
||||||
|
#include "LEDController.h"
|
||||||
|
|
||||||
|
class LCDController {
|
||||||
|
private:
|
||||||
|
FILE* _lcdOutput;
|
||||||
|
LiquidCrystal* _lcd;
|
||||||
|
int _lcdCols;
|
||||||
|
int _lcdRows;
|
||||||
|
int _cursorRow;
|
||||||
|
int _cursorCol;
|
||||||
|
|
||||||
|
static int lcdPutchar(char c, FILE* stream);
|
||||||
|
static LCDController* _instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LCDController(uint8_t rs, uint8_t enable, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
||||||
|
int cols = 16, int rows = 2);
|
||||||
|
~LCDController();
|
||||||
|
void begin();
|
||||||
|
FILE* stream();
|
||||||
|
void clear();
|
||||||
|
void setCursor(int col, int row);
|
||||||
|
void print(const char* text);
|
||||||
|
|
||||||
|
static LCDController* getInstance() { return _instance; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
31
include/drivers/LEDController.h
Normal file
31
include/drivers/LEDController.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef LED_CONTROLLER_H
|
||||||
|
#define LED_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class LEDController {
|
||||||
|
private:
|
||||||
|
const int _ledPin;
|
||||||
|
bool _state;
|
||||||
|
bool _isBlinking;
|
||||||
|
unsigned long _previousMillis;
|
||||||
|
unsigned long _blinkInterval;
|
||||||
|
unsigned long _blinkCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LEDController(int ledPin);
|
||||||
|
LEDController(int ledPin, bool state);
|
||||||
|
void turnOn();
|
||||||
|
void turnOff();
|
||||||
|
void toggle();
|
||||||
|
bool getState() const;
|
||||||
|
void blink(bool enable);
|
||||||
|
bool isBlinkingEnabled() const;
|
||||||
|
void interval(unsigned long interval);
|
||||||
|
unsigned long getBlinkInterval() const;
|
||||||
|
unsigned long getBlinkCount() const;
|
||||||
|
void tick();
|
||||||
|
void set(bool value);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
24
include/drivers/MotorController.h
Normal file
24
include/drivers/MotorController.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef DC_MOTOR_DRIVER_H
|
||||||
|
#define DC_MOTOR_DRIVER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class MotorController {
|
||||||
|
private:
|
||||||
|
const int _pinIA;
|
||||||
|
const int _pinIB;
|
||||||
|
int _currentPower;
|
||||||
|
|
||||||
|
void applyPower();
|
||||||
|
|
||||||
|
public:
|
||||||
|
MotorController(int pinIA, int pinIB);
|
||||||
|
void set(int power);
|
||||||
|
void stop();
|
||||||
|
void maximum();
|
||||||
|
void inc();
|
||||||
|
void dec();
|
||||||
|
int getPower() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
0
include/drivers/PassiveBuzzerController.h
Normal file
0
include/drivers/PassiveBuzzerController.h
Normal file
35
include/drivers/PhotoresistorController.h
Normal file
35
include/drivers/PhotoresistorController.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef PHOTORESISTOR_CONTROLLER_H
|
||||||
|
#define PHOTORESISTOR_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define DEFAULT_MIN_READ_INTERVAL 50
|
||||||
|
#define DEFAULT_SAMPLES 3
|
||||||
|
|
||||||
|
class PhotoresistorController {
|
||||||
|
private:
|
||||||
|
uint8_t _pin;
|
||||||
|
unsigned long _lastReadTime;
|
||||||
|
unsigned long _minReadInterval;
|
||||||
|
int _lastRawValue;
|
||||||
|
int _lastPercentValue;
|
||||||
|
bool _lastReadSuccess;
|
||||||
|
uint8_t _numSamples;
|
||||||
|
int _maxValue;
|
||||||
|
int _minValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PhotoresistorController(uint8_t pin, int minValue = 0, int maxValue = 1023);
|
||||||
|
void begin();
|
||||||
|
bool read();
|
||||||
|
int getRawValue();
|
||||||
|
int getPercentValue();
|
||||||
|
void calibrate(int minValue, int maxValue);
|
||||||
|
void autoCalibrateDark();
|
||||||
|
void autoCalibrateBright();
|
||||||
|
bool isLastReadSuccessful() const;
|
||||||
|
void setMinReadInterval(unsigned long interval);
|
||||||
|
void setNumSamples(uint8_t samples);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
0
include/drivers/RGBLEDController.h
Normal file
0
include/drivers/RGBLEDController.h
Normal file
38
include/drivers/RelayController.h
Normal file
38
include/drivers/RelayController.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef RELAY_CONTROLLER_H
|
||||||
|
#define RELAY_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class RelayController {
|
||||||
|
private:
|
||||||
|
const int _relayPin;
|
||||||
|
bool _isConnected;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RelayController(int relayPin) :
|
||||||
|
_relayPin(relayPin),
|
||||||
|
_isConnected(false) {
|
||||||
|
pinMode(_relayPin, OUTPUT);
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect() {
|
||||||
|
digitalWrite(_relayPin, LOW);
|
||||||
|
_isConnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnect() {
|
||||||
|
digitalWrite(_relayPin, HIGH);
|
||||||
|
_isConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isConnected() const {
|
||||||
|
return _isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getPin() const {
|
||||||
|
return _relayPin;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
54
include/drivers/ThermistorController.h
Normal file
54
include/drivers/ThermistorController.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef THERMISTOR_CONTROLLER_H
|
||||||
|
#define THERMISTOR_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class ThermistorController {
|
||||||
|
private:
|
||||||
|
const int _thermistorPin;
|
||||||
|
const float _seriesResistor;
|
||||||
|
const float _bParameter;
|
||||||
|
const float _nominalTemp;
|
||||||
|
|
||||||
|
static const int _bufferSize = 10;
|
||||||
|
float _rawReadings[_bufferSize];
|
||||||
|
int _bufferIndex;
|
||||||
|
bool _bufferFilled;
|
||||||
|
|
||||||
|
float _filteredRaw;
|
||||||
|
float _smoothedRaw;
|
||||||
|
float _resistance;
|
||||||
|
float _temperatureC;
|
||||||
|
|
||||||
|
const float _weights[_bufferSize] = {0.05, 0.05, 0.05, 0.05, 0.1, 0.1, 0.1, 0.15, 0.15, 0.2};
|
||||||
|
|
||||||
|
const float _minTemp;
|
||||||
|
const float _maxTemp;
|
||||||
|
|
||||||
|
float applySaltPepperFilter();
|
||||||
|
float applyWeightedMovingAverage();
|
||||||
|
float calculateResistance(float adcValue);
|
||||||
|
float calculateTemperature(float resistance);
|
||||||
|
float applySaturation(float value, float min, float max);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThermistorController(
|
||||||
|
int thermistorPin,
|
||||||
|
float seriesResistor = 10000.0,
|
||||||
|
float bParameter = 3435.0,
|
||||||
|
float nominalTemp = 25.0,
|
||||||
|
float minTemp = -55.0,
|
||||||
|
float maxTemp = 125.0
|
||||||
|
);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
float getRawValue() const;
|
||||||
|
float getFilteredRaw() const;
|
||||||
|
float getSmoothedRaw() const;
|
||||||
|
float getResistance() const;
|
||||||
|
float getTemperatureC() const;
|
||||||
|
float getTemperatureF() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
24
include/labs/Lab2_1.h
Normal file
24
include/labs/Lab2_1.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef LAB2_1_H
|
||||||
|
#define LAB2_1_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LEDController.h"
|
||||||
|
#include "drivers/ButtonController.h"
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
|
||||||
|
#define BUTTON_TOGGLE_PIN 13
|
||||||
|
#define BUTTON_INCREMENT_PIN 11
|
||||||
|
#define BUTTON_DECREMENT_PIN 12
|
||||||
|
#define LED_PIN 22
|
||||||
|
#define LED_BLINK_PIN 24
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
|
||||||
|
void Lab2_1Task(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
33
include/labs/Lab2_2.h
Normal file
33
include/labs/Lab2_2.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef LAB2_2_H
|
||||||
|
#define LAB2_2_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include <semphr.h>
|
||||||
|
#include <queue.h>
|
||||||
|
#include "drivers/LEDController.h"
|
||||||
|
#include "drivers/ButtonController.h"
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
|
||||||
|
#define LED_BUTTON_PIN 28
|
||||||
|
#define LED_BLINK_PIN 24
|
||||||
|
#define BUTTON_PIN 13
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ButtonController* button;
|
||||||
|
LEDController* led;
|
||||||
|
LEDController* blinkLed;
|
||||||
|
LCDController* lcd;
|
||||||
|
SemaphoreHandle_t buttonSemaphore;
|
||||||
|
QueueHandle_t dataQueue;
|
||||||
|
} TaskParameters;
|
||||||
|
|
||||||
|
void Lab2_2Task(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
33
include/labs/Lab3_1.h
Normal file
33
include/labs/Lab3_1.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef LAB3_1_H
|
||||||
|
#define LAB3_1_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
#include "drivers/JoystickController.h"
|
||||||
|
#include "drivers/DHTController.h"
|
||||||
|
#include "drivers/AccelerometerController.h"
|
||||||
|
#include "drivers/PhotoresistorController.h"
|
||||||
|
#include "drivers/DistanceSensorController.h"
|
||||||
|
|
||||||
|
#define VRX A0
|
||||||
|
#define VRY A1
|
||||||
|
#define SW 15
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
#define DHT_PIN 4
|
||||||
|
#define PHOTORESISTOR_PIN A3
|
||||||
|
#define TRIG_PIN 5
|
||||||
|
#define ECHO_PIN 6
|
||||||
|
|
||||||
|
void Lab3_1Task(void* pv);
|
||||||
|
void DHTTask(void* pv);
|
||||||
|
void AccelerometerTask(void* pv);
|
||||||
|
void PhotoresistorTask(void*pv);
|
||||||
|
void DistanceTask(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
19
include/labs/Lab3_2.h
Normal file
19
include/labs/Lab3_2.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef LAB3_2_H
|
||||||
|
#define LAB3_2_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
#include "drivers/ThermistorController.h"
|
||||||
|
|
||||||
|
#define THERMISTOR_PIN A2
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
|
||||||
|
void Lab3_2Task(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
23
include/labs/Lab4_1.h
Normal file
23
include/labs/Lab4_1.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef LAB4_1_H
|
||||||
|
#define LAB4_1_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
#include "drivers/JoystickController.h"
|
||||||
|
#include "drivers/RelayController.h"
|
||||||
|
|
||||||
|
#define VRX A0
|
||||||
|
#define VRY A1
|
||||||
|
#define SW 15
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
#define RELAY_PIN 14
|
||||||
|
|
||||||
|
void Lab4_1Task(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
26
include/labs/Lab4_2.h
Normal file
26
include/labs/Lab4_2.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef LAB4_2_H
|
||||||
|
#define LAB4_2_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
#include "drivers/JoystickController.h"
|
||||||
|
#include "drivers/RelayController.h"
|
||||||
|
#include "drivers/MotorController.h"
|
||||||
|
|
||||||
|
#define MOTOR_PIN_IA 2
|
||||||
|
#define MOTOR_PIN_IB 3
|
||||||
|
#define RELAY_PIN 14
|
||||||
|
#define VRX A0
|
||||||
|
#define VRY A1
|
||||||
|
#define SW 15
|
||||||
|
#define RS 31
|
||||||
|
#define EN 33
|
||||||
|
#define D4 35
|
||||||
|
#define D5 37
|
||||||
|
#define D6 39
|
||||||
|
#define D7 41
|
||||||
|
|
||||||
|
void Lab4_2Task(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
21
include/labs/LabSelector.h
Normal file
21
include/labs/LabSelector.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef LABSELECTOR_H
|
||||||
|
#define LABSELECTOR_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
#include "drivers/LCDController.h"
|
||||||
|
#include "drivers/JoystickController.h"
|
||||||
|
#include "Lab2_1.h"
|
||||||
|
#include "Lab2_2.h"
|
||||||
|
#include "Lab3_1.h"
|
||||||
|
#include "Lab3_2.h"
|
||||||
|
#include "Lab4_1.h"
|
||||||
|
#include "Lab4_2.h"
|
||||||
|
|
||||||
|
#define VRX A0
|
||||||
|
#define VRY A1
|
||||||
|
#define SW 15
|
||||||
|
|
||||||
|
void LabSelectorTask(void* pv);
|
||||||
|
|
||||||
|
#endif
|
||||||
19
platformio.ini
Normal file
19
platformio.ini
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:megaatmega2560]
|
||||||
|
platform = atmelavr
|
||||||
|
board = megaatmega2560
|
||||||
|
framework = arduino
|
||||||
|
lib_deps =
|
||||||
|
adafruit/DHT sensor library@^1.4.6
|
||||||
|
feilipu/FreeRTOS@^10.5.1-0
|
||||||
|
arduino-libraries/LiquidCrystal@^1.0.7
|
||||||
130
src/drivers/AccelerometerController.cpp
Normal file
130
src/drivers/AccelerometerController.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "drivers/AccelerometerController.h"
|
||||||
|
|
||||||
|
ADXL345Controller::ADXL345Controller(uint8_t deviceAddress) :
|
||||||
|
_deviceAddress(deviceAddress),
|
||||||
|
_lastReadTime(0),
|
||||||
|
_minReadInterval(DEFAULT_MIN_READ_INTERVAL),
|
||||||
|
_lastX(0.0),
|
||||||
|
_lastY(0.0),
|
||||||
|
_lastZ(0.0),
|
||||||
|
_lastReadSuccess(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::begin() {
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
uint8_t deviceID = readRegister(ADXL345_DEVID);
|
||||||
|
if (deviceID != 0xE5) {
|
||||||
|
_lastReadSuccess = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRegister(ADXL345_POWER_CTL, 0x08);
|
||||||
|
|
||||||
|
setRegister(ADXL345_DATA_FORMAT, 0x0B);
|
||||||
|
|
||||||
|
setRegister(ADXL345_BW_RATE, 0x0A);
|
||||||
|
|
||||||
|
setRegister(ADXL345_OFSX, 0x00);
|
||||||
|
setRegister(ADXL345_OFSY, 0x00);
|
||||||
|
setRegister(ADXL345_OFSZ, 0x00);
|
||||||
|
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ADXL345Controller::read() {
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
if (currentTime - _lastReadTime >= _minReadInterval) {
|
||||||
|
_lastReadTime = currentTime;
|
||||||
|
|
||||||
|
uint8_t buffer[6];
|
||||||
|
readRegisters(ADXL345_DATAX0, 6, buffer);
|
||||||
|
|
||||||
|
int16_t x = ((int16_t)buffer[1] << 8) | buffer[0];
|
||||||
|
int16_t y = ((int16_t)buffer[3] << 8) | buffer[2];
|
||||||
|
int16_t z = ((int16_t)buffer[5] << 8) | buffer[4];
|
||||||
|
|
||||||
|
_lastX = x / 256.0;
|
||||||
|
_lastY = y / 256.0;
|
||||||
|
_lastZ = z / 256.0;
|
||||||
|
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ADXL345Controller::getX() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastX;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ADXL345Controller::getY() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ADXL345Controller::getZ() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ADXL345Controller::isLastReadSuccessful() const {
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::setMinReadInterval(unsigned long interval) {
|
||||||
|
_minReadInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::setRange(uint8_t range) {
|
||||||
|
uint8_t format = readRegister(ADXL345_DATA_FORMAT);
|
||||||
|
|
||||||
|
format &= ~0x03;
|
||||||
|
|
||||||
|
if (range > 3) range = 3;
|
||||||
|
format |= range;
|
||||||
|
|
||||||
|
setRegister(ADXL345_DATA_FORMAT, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::setDataRate(uint8_t rate) {
|
||||||
|
if (rate > 15) rate = 15;
|
||||||
|
|
||||||
|
setRegister(ADXL345_BW_RATE, rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::setOffsets(int8_t xOffset, int8_t yOffset, int8_t zOffset) {
|
||||||
|
setRegister(ADXL345_OFSX, xOffset);
|
||||||
|
setRegister(ADXL345_OFSY, yOffset);
|
||||||
|
setRegister(ADXL345_OFSZ, zOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::setRegister(uint8_t reg, uint8_t value) {
|
||||||
|
Wire.beginTransmission(_deviceAddress);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.write(value);
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ADXL345Controller::readRegister(uint8_t reg) {
|
||||||
|
Wire.beginTransmission(_deviceAddress);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(_deviceAddress, (uint8_t)1);
|
||||||
|
return Wire.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADXL345Controller::readRegisters(uint8_t reg, uint8_t count, uint8_t *buffer) {
|
||||||
|
Wire.beginTransmission(_deviceAddress);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.endTransmission();
|
||||||
|
|
||||||
|
Wire.requestFrom(_deviceAddress, count);
|
||||||
|
for (uint8_t i = 0; i < count && Wire.available(); i++) {
|
||||||
|
buffer[i] = Wire.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/drivers/ButtonController.cpp
Normal file
44
src/drivers/ButtonController.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "drivers/ButtonController.h"
|
||||||
|
|
||||||
|
ButtonController::ButtonController(int buttonPin, unsigned long debounceDelay) :
|
||||||
|
_buttonPin(buttonPin),
|
||||||
|
_lastDebounceTime(0),
|
||||||
|
_debounceDelay(debounceDelay),
|
||||||
|
_lastButtonState(HIGH),
|
||||||
|
_buttonState(HIGH) {
|
||||||
|
|
||||||
|
pinMode(_buttonPin, INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ButtonController::wasOn() {
|
||||||
|
bool result = false;
|
||||||
|
int reading = digitalRead(_buttonPin);
|
||||||
|
|
||||||
|
if (reading != _lastButtonState) _lastDebounceTime = millis();
|
||||||
|
|
||||||
|
if ((millis() - _lastDebounceTime) > _debounceDelay) {
|
||||||
|
if (reading != _buttonState) {
|
||||||
|
_buttonState = reading;
|
||||||
|
if (_buttonState == LOW) result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastButtonState = reading;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonController::tick() {
|
||||||
|
int reading = digitalRead(_buttonPin);
|
||||||
|
|
||||||
|
if (reading != _lastButtonState) _lastDebounceTime = millis();
|
||||||
|
|
||||||
|
if ((millis() - _lastDebounceTime) > _debounceDelay)
|
||||||
|
if (reading != _buttonState) _buttonState = reading;
|
||||||
|
|
||||||
|
_lastButtonState = reading;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ButtonController::getState() const {
|
||||||
|
return _buttonState;
|
||||||
|
}
|
||||||
58
src/drivers/DHTController.cpp
Normal file
58
src/drivers/DHTController.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "drivers/DHTController.h"
|
||||||
|
|
||||||
|
#define DEFAULT_MIN_READ_INTERVAL 2000
|
||||||
|
|
||||||
|
DHTController::DHTController(uint8_t pin, uint8_t type) :
|
||||||
|
_dht(pin, type),
|
||||||
|
_lastReadTime(0),
|
||||||
|
_minReadInterval(DEFAULT_MIN_READ_INTERVAL),
|
||||||
|
_lastTemperature(0.0f),
|
||||||
|
_lastHumidity(0.0f),
|
||||||
|
_lastReadSuccess(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHTController::begin() {
|
||||||
|
_dht.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DHTController::read() {
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
if (currentTime - _lastReadTime >= _minReadInterval) {
|
||||||
|
_lastReadTime = currentTime;
|
||||||
|
|
||||||
|
float humidity = _dht.readHumidity();
|
||||||
|
|
||||||
|
float temperature = _dht.readTemperature();
|
||||||
|
|
||||||
|
if (isnan(humidity) || isnan(temperature)) {
|
||||||
|
_lastReadSuccess = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastHumidity = humidity;
|
||||||
|
_lastTemperature = temperature;
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DHTController::getTemperature() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastTemperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DHTController::getHumidity() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastHumidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DHTController::isLastReadSuccessful() const {
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHTController::setMinReadInterval(unsigned long interval) {
|
||||||
|
_minReadInterval = interval;
|
||||||
|
}
|
||||||
99
src/drivers/DistanceSensorController.cpp
Normal file
99
src/drivers/DistanceSensorController.cpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#include "drivers/DistanceSensorController.h"
|
||||||
|
|
||||||
|
DistanceSensorController::DistanceSensorController(uint8_t trigPin, uint8_t echoPin) :
|
||||||
|
_trigPin(trigPin),
|
||||||
|
_echoPin(echoPin),
|
||||||
|
_lastReadTime(0),
|
||||||
|
_minReadInterval(DEFAULT_MIN_READ_INTERVAL_DIST),
|
||||||
|
_lastDistanceCm(0),
|
||||||
|
_lastReadSuccess(false),
|
||||||
|
_numSamples(DEFAULT_SAMPLES),
|
||||||
|
_timeout(30000) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DistanceSensorController::begin() {
|
||||||
|
pinMode(_trigPin, OUTPUT);
|
||||||
|
pinMode(_echoPin, INPUT);
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DistanceSensorController::read() {
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
if (currentTime - _lastReadTime >= _minReadInterval) {
|
||||||
|
_lastReadTime = currentTime;
|
||||||
|
|
||||||
|
long sum = 0;
|
||||||
|
int validSamples = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < _numSamples; i++) {
|
||||||
|
long measurement = takeMeasurement();
|
||||||
|
|
||||||
|
if (measurement > 0 && measurement < MAX_DISTANCE) {
|
||||||
|
sum += measurement;
|
||||||
|
validSamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_numSamples > 1) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validSamples > 0) {
|
||||||
|
_lastDistanceCm = sum / validSamples;
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
} else {
|
||||||
|
_lastReadSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
long DistanceSensorController::takeMeasurement() {
|
||||||
|
digitalWrite(_trigPin, LOW);
|
||||||
|
delayMicroseconds(2);
|
||||||
|
|
||||||
|
digitalWrite(_trigPin, HIGH);
|
||||||
|
delayMicroseconds(10);
|
||||||
|
digitalWrite(_trigPin, LOW);
|
||||||
|
|
||||||
|
long duration = pulseIn(_echoPin, HIGH, _timeout);
|
||||||
|
|
||||||
|
return microsecondsToCentimeters(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
long DistanceSensorController::microsecondsToCentimeters(long microseconds) {
|
||||||
|
if (microseconds == 0) return 0;
|
||||||
|
return microseconds / 29 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
long DistanceSensorController::getDistanceCm() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastDistanceCm;
|
||||||
|
}
|
||||||
|
|
||||||
|
long DistanceSensorController::getDistanceInch() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastDistanceCm / 2.54;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DistanceSensorController::isLastReadSuccessful() const {
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DistanceSensorController::setMinReadInterval(unsigned long interval) {
|
||||||
|
_minReadInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DistanceSensorController::setNumSamples(uint8_t samples) {
|
||||||
|
if (samples > 0) {
|
||||||
|
_numSamples = samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DistanceSensorController::setTimeout(unsigned long timeout) {
|
||||||
|
_timeout = timeout;
|
||||||
|
}
|
||||||
177
src/drivers/JoystickController.cpp
Normal file
177
src/drivers/JoystickController.cpp
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#include "drivers/JoystickController.h"
|
||||||
|
|
||||||
|
JoystickController* JoystickController::_instance = nullptr;
|
||||||
|
|
||||||
|
JoystickController::JoystickController(uint8_t xPin, uint8_t yPin, uint8_t buttonPin) {
|
||||||
|
pinX = xPin;
|
||||||
|
pinY = yPin;
|
||||||
|
pinButton = buttonPin;
|
||||||
|
|
||||||
|
centerX = 512;
|
||||||
|
centerY = 512;
|
||||||
|
deadzone = 100;
|
||||||
|
debounceDelay = 10;
|
||||||
|
lastDebounceTime = 0;
|
||||||
|
|
||||||
|
lastX = centerX;
|
||||||
|
lastY = centerY;
|
||||||
|
lastButtonState = false;
|
||||||
|
|
||||||
|
pinMode(pinX, INPUT);
|
||||||
|
pinMode(pinY, INPUT);
|
||||||
|
|
||||||
|
if (pinButton != 255) {
|
||||||
|
pinMode(pinButton, INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
_instance = this;
|
||||||
|
|
||||||
|
calibrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
JoystickController::~JoystickController() {
|
||||||
|
if (_instance == this) _instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::readRawValues() {
|
||||||
|
rawX = analogRead(pinX);
|
||||||
|
rawY = analogRead(pinY);
|
||||||
|
|
||||||
|
if (pinButton != 255) {
|
||||||
|
buttonState = !digitalRead(pinButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::begin() {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
readRawValues();
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
calibrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::calibrate() {
|
||||||
|
int sumX = 0;
|
||||||
|
int sumY = 0;
|
||||||
|
const int samples = 20;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
readRawValues();
|
||||||
|
sumX += rawX;
|
||||||
|
sumY += rawY;
|
||||||
|
delay(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
centerX = sumX / samples;
|
||||||
|
centerY = sumY / samples;
|
||||||
|
|
||||||
|
lastX = centerX;
|
||||||
|
lastY = centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::setDeadzone(int value) {
|
||||||
|
deadzone = constrain(value, 0, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::setDebounceDelay(int delayMs) {
|
||||||
|
debounceDelay = delayMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoystickController::tick() {
|
||||||
|
readRawValues();
|
||||||
|
|
||||||
|
if ((millis() - lastDebounceTime) > debounceDelay) {
|
||||||
|
if (abs(rawX - lastX) > deadzone || abs(rawY - lastY) > deadzone || buttonState != lastButtonState) {
|
||||||
|
lastX = rawX;
|
||||||
|
lastY = rawY;
|
||||||
|
lastButtonState = buttonState;
|
||||||
|
lastDebounceTime = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getRawX() {
|
||||||
|
return rawX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getRawY() {
|
||||||
|
return rawY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getX() {
|
||||||
|
return lastX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getY() {
|
||||||
|
return lastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getOffsetX() {
|
||||||
|
return lastX - centerX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getOffsetY() {
|
||||||
|
return lastY - centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JoystickController::isPressed() {
|
||||||
|
return lastButtonState;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JoystickController::isCentered() {
|
||||||
|
return (abs(lastX - centerX) <= deadzone && abs(lastY - centerY) <= deadzone);
|
||||||
|
}
|
||||||
|
|
||||||
|
JoystickDirection JoystickController::getDirection() {
|
||||||
|
int dx = lastX - centerX;
|
||||||
|
int dy = lastY - centerY;
|
||||||
|
|
||||||
|
if (abs(dx) <= deadzone && abs(dy) <= deadzone) {
|
||||||
|
return CENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
float angle = atan2(-dy, dx) * 180 / PI;
|
||||||
|
|
||||||
|
float adjusted = angle + 22.5;
|
||||||
|
if (adjusted < 0) adjusted += 360;
|
||||||
|
|
||||||
|
int sector = int(adjusted / 45) % 8;
|
||||||
|
|
||||||
|
switch (sector) {
|
||||||
|
case 0: return RIGHT;
|
||||||
|
case 1: return UP_RIGHT;
|
||||||
|
case 2: return UP;
|
||||||
|
case 3: return UP_LEFT;
|
||||||
|
case 4: return LEFT;
|
||||||
|
case 5: return DOWN_LEFT;
|
||||||
|
case 6: return DOWN;
|
||||||
|
case 7: return DOWN_RIGHT;
|
||||||
|
default: return CENTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String JoystickController::getDirectionString() {
|
||||||
|
JoystickDirection dir = getDirection();
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case CENTER: return "CENTER";
|
||||||
|
case UP: return "UP";
|
||||||
|
case UP_RIGHT: return "UP_RIGHT";
|
||||||
|
case RIGHT: return "RIGHT";
|
||||||
|
case DOWN_RIGHT:return "DOWN_RIGHT";
|
||||||
|
case DOWN: return "DOWN";
|
||||||
|
case DOWN_LEFT: return "DOWN_LEFT";
|
||||||
|
case LEFT: return "LEFT";
|
||||||
|
case UP_LEFT: return "UP_LEFT";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int JoystickController::getDistancePercent() {
|
||||||
|
int dx = lastX - centerX;
|
||||||
|
int dy = lastY - centerY;
|
||||||
|
float distance = sqrt(dx*dx + dy*dy);
|
||||||
|
|
||||||
|
return constrain(map(distance, deadzone, 512, 0, 100), 0, 100);
|
||||||
|
}
|
||||||
89
src/drivers/LCDController.cpp
Normal file
89
src/drivers/LCDController.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#include "drivers/LCDController.h"
|
||||||
|
|
||||||
|
LCDController* LCDController::_instance = nullptr;
|
||||||
|
|
||||||
|
int LCDController::lcdPutchar(char c, FILE* stream) {
|
||||||
|
if (_instance && _instance->_lcd) {
|
||||||
|
if (c == '\n') {
|
||||||
|
_instance->_cursorRow = (_instance->_cursorRow + 1) % _instance->_lcdRows;
|
||||||
|
_instance->_cursorCol = 0;
|
||||||
|
_instance->_lcd->setCursor(_instance->_cursorCol, _instance->_cursorRow);
|
||||||
|
}
|
||||||
|
else if (c == '\r') {
|
||||||
|
_instance->_cursorCol = 0;
|
||||||
|
_instance->_lcd->setCursor(_instance->_cursorCol, _instance->_cursorRow);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_instance->_lcd->write(c);
|
||||||
|
_instance->_cursorCol++;
|
||||||
|
|
||||||
|
if (_instance->_cursorCol >= _instance->_lcdCols) {
|
||||||
|
_instance->_cursorRow = (_instance->_cursorRow + 1) % _instance->_lcdRows;
|
||||||
|
_instance->_cursorCol = 0;
|
||||||
|
_instance->_lcd->setCursor(_instance->_cursorCol, _instance->_cursorRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LCDController::LCDController(uint8_t rs, uint8_t enable, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
|
||||||
|
int cols, int rows) :
|
||||||
|
_lcdOutput(nullptr),
|
||||||
|
_lcdCols(cols),
|
||||||
|
_lcdRows(rows),
|
||||||
|
_cursorRow(0),
|
||||||
|
_cursorCol(0) {
|
||||||
|
|
||||||
|
_lcd = new LiquidCrystal(rs, enable, d4, d5, d6, d7);
|
||||||
|
_instance = this;
|
||||||
|
|
||||||
|
begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
LCDController::~LCDController() {
|
||||||
|
if (_lcdOutput) fclose(_lcdOutput);
|
||||||
|
if (_lcd) delete _lcd;
|
||||||
|
_instance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LCDController::begin() {
|
||||||
|
_lcd->begin(_lcdCols, _lcdRows);
|
||||||
|
_lcd->clear();
|
||||||
|
|
||||||
|
_lcdOutput = fdevopen(lcdPutchar, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* LCDController::stream() {
|
||||||
|
return _lcdOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LCDController::clear() {
|
||||||
|
if (_lcd) {
|
||||||
|
_lcd->clear();
|
||||||
|
_cursorRow = 0;
|
||||||
|
_cursorCol = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LCDController::setCursor(int col, int row) {
|
||||||
|
if (_lcd) {
|
||||||
|
_cursorCol = col;
|
||||||
|
_cursorRow = row;
|
||||||
|
_lcd->setCursor(col, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LCDController::print(const char* text) {
|
||||||
|
if (_lcd) {
|
||||||
|
_lcd->print(text);
|
||||||
|
|
||||||
|
int len = strlen(text);
|
||||||
|
_cursorCol += len;
|
||||||
|
|
||||||
|
while (_cursorCol >= _lcdCols) {
|
||||||
|
_cursorCol -= _lcdCols;
|
||||||
|
_cursorRow = (_cursorRow + 1) % _lcdRows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
src/drivers/LEDController.cpp
Normal file
88
src/drivers/LEDController.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include "drivers/LEDController.h"
|
||||||
|
|
||||||
|
#define BLINK_INTERVAL 500
|
||||||
|
|
||||||
|
LEDController::LEDController(int ledPin) :
|
||||||
|
_ledPin(ledPin),
|
||||||
|
_state(false),
|
||||||
|
_isBlinking(false),
|
||||||
|
_previousMillis(0),
|
||||||
|
_blinkInterval(BLINK_INTERVAL),
|
||||||
|
_blinkCount(0) {
|
||||||
|
|
||||||
|
pinMode(_ledPin, OUTPUT);
|
||||||
|
digitalWrite(_ledPin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
LEDController::LEDController(int ledPin, bool state) :
|
||||||
|
_ledPin(ledPin),
|
||||||
|
_state(state),
|
||||||
|
_isBlinking(false),
|
||||||
|
_previousMillis(0),
|
||||||
|
_blinkInterval(BLINK_INTERVAL),
|
||||||
|
_blinkCount(0) {
|
||||||
|
|
||||||
|
pinMode(_ledPin, OUTPUT);
|
||||||
|
|
||||||
|
if (state) digitalWrite(_ledPin, HIGH);
|
||||||
|
else digitalWrite(_ledPin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::turnOn() {
|
||||||
|
_state = true;
|
||||||
|
digitalWrite(_ledPin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::turnOff() {
|
||||||
|
_state = false;
|
||||||
|
digitalWrite(_ledPin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::toggle() {
|
||||||
|
_state = !_state;
|
||||||
|
digitalWrite(_ledPin, _state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LEDController::getState() const {
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::blink(bool enable) {
|
||||||
|
_isBlinking = enable;
|
||||||
|
if (!enable) {
|
||||||
|
turnOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LEDController::isBlinkingEnabled() const {
|
||||||
|
return _isBlinking;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::interval(unsigned long interval) {
|
||||||
|
_blinkInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long LEDController::getBlinkInterval() const {
|
||||||
|
return _blinkInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long LEDController::getBlinkCount() const {
|
||||||
|
return _blinkCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::tick() {
|
||||||
|
if (_isBlinking) {
|
||||||
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
|
if (currentMillis - _previousMillis >= _blinkInterval) {
|
||||||
|
_previousMillis = currentMillis;
|
||||||
|
toggle();
|
||||||
|
if (_state)_blinkCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDController::set(bool value) {
|
||||||
|
if (value) turnOn();
|
||||||
|
else turnOff();
|
||||||
|
}
|
||||||
71
src/drivers/MotorController.cpp
Normal file
71
src/drivers/MotorController.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#include "drivers/MotorController.h"
|
||||||
|
|
||||||
|
MotorController::MotorController(int pinIA, int pinIB) :
|
||||||
|
_pinIA(pinIA),
|
||||||
|
_pinIB(pinIB),
|
||||||
|
_currentPower(0) {
|
||||||
|
|
||||||
|
pinMode(_pinIA, OUTPUT);
|
||||||
|
pinMode(_pinIB, OUTPUT);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::applyPower() {
|
||||||
|
if (_currentPower == 0) {
|
||||||
|
analogWrite(_pinIA, 0);
|
||||||
|
analogWrite(_pinIB, 0);
|
||||||
|
} else if (_currentPower > 0) {
|
||||||
|
int pwmValue = map(abs(_currentPower), 0, 100, 0, 255);
|
||||||
|
analogWrite(_pinIA, pwmValue);
|
||||||
|
analogWrite(_pinIB, 0);
|
||||||
|
} else {
|
||||||
|
int pwmValue = map(abs(_currentPower), 0, 100, 0, 255);
|
||||||
|
analogWrite(_pinIA, 0);
|
||||||
|
analogWrite(_pinIB, pwmValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::set(int power) {
|
||||||
|
_currentPower = constrain(power, -100, 100);
|
||||||
|
applyPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::stop() {
|
||||||
|
_currentPower = 0;
|
||||||
|
applyPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::maximum() {
|
||||||
|
if (_currentPower >= 0) {
|
||||||
|
_currentPower = 100;
|
||||||
|
} else {
|
||||||
|
_currentPower = -100;
|
||||||
|
}
|
||||||
|
applyPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::inc() {
|
||||||
|
if (_currentPower == 0) {
|
||||||
|
_currentPower = 10;
|
||||||
|
} else {
|
||||||
|
if (_currentPower > 0) {
|
||||||
|
_currentPower = min(100, _currentPower + 10);
|
||||||
|
} else {
|
||||||
|
_currentPower = max(-100, _currentPower - 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applyPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorController::dec() {
|
||||||
|
if (_currentPower > 0) {
|
||||||
|
_currentPower = max(0, _currentPower - 10);
|
||||||
|
} else if (_currentPower < 0) {
|
||||||
|
_currentPower = min(0, _currentPower + 10);
|
||||||
|
}
|
||||||
|
applyPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MotorController::getPower() const {
|
||||||
|
return _currentPower;
|
||||||
|
}
|
||||||
0
src/drivers/PassiveBuzzerController.cpp
Normal file
0
src/drivers/PassiveBuzzerController.cpp
Normal file
90
src/drivers/PhotoresistorController.cpp
Normal file
90
src/drivers/PhotoresistorController.cpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "drivers/PhotoresistorController.h"
|
||||||
|
|
||||||
|
PhotoresistorController::PhotoresistorController(uint8_t pin, int minValue, int maxValue) :
|
||||||
|
_pin(pin),
|
||||||
|
_lastReadTime(0),
|
||||||
|
_minReadInterval(DEFAULT_MIN_READ_INTERVAL),
|
||||||
|
_lastRawValue(0),
|
||||||
|
_lastPercentValue(0),
|
||||||
|
_lastReadSuccess(false),
|
||||||
|
_numSamples(DEFAULT_SAMPLES),
|
||||||
|
_maxValue(maxValue),
|
||||||
|
_minValue(minValue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::begin() {
|
||||||
|
pinMode(_pin, INPUT);
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhotoresistorController::read() {
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
if (currentTime - _lastReadTime >= _minReadInterval) {
|
||||||
|
_lastReadTime = currentTime;
|
||||||
|
|
||||||
|
long sum = 0;
|
||||||
|
for (uint8_t i = 0; i < _numSamples; i++) {
|
||||||
|
sum += analogRead(_pin);
|
||||||
|
if (_numSamples > 1) {
|
||||||
|
delay(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastRawValue = sum / _numSamples;
|
||||||
|
|
||||||
|
long range = _maxValue - _minValue;
|
||||||
|
if (range <= 0) {
|
||||||
|
_lastPercentValue = 50;
|
||||||
|
} else {
|
||||||
|
int constrainedValue = constrain(_lastRawValue, _minValue, _maxValue);
|
||||||
|
_lastPercentValue = map(constrainedValue, _minValue, _maxValue, 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastReadSuccess = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PhotoresistorController::getRawValue() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastRawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PhotoresistorController::getPercentValue() {
|
||||||
|
if (millis() - _lastReadTime >= _minReadInterval) read();
|
||||||
|
return _lastPercentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::calibrate(int minValue, int maxValue) {
|
||||||
|
if (minValue < maxValue) {
|
||||||
|
_minValue = minValue;
|
||||||
|
_maxValue = maxValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::autoCalibrateDark() {
|
||||||
|
read();
|
||||||
|
_minValue = _lastRawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::autoCalibrateBright() {
|
||||||
|
read();
|
||||||
|
_maxValue = _lastRawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhotoresistorController::isLastReadSuccessful() const {
|
||||||
|
return _lastReadSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::setMinReadInterval(unsigned long interval) {
|
||||||
|
_minReadInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorController::setNumSamples(uint8_t samples) {
|
||||||
|
if (samples > 0) {
|
||||||
|
_numSamples = samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/drivers/RGBLEDController.cpp
Normal file
0
src/drivers/RGBLEDController.cpp
Normal file
121
src/drivers/ThermistorController.cpp
Normal file
121
src/drivers/ThermistorController.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#include "drivers/ThermistorController.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
ThermistorController::ThermistorController(
|
||||||
|
int thermistorPin,
|
||||||
|
float seriesResistor,
|
||||||
|
float bParameter,
|
||||||
|
float nominalTemp,
|
||||||
|
float minTemp,
|
||||||
|
float maxTemp
|
||||||
|
) :
|
||||||
|
_thermistorPin(thermistorPin),
|
||||||
|
_seriesResistor(seriesResistor),
|
||||||
|
_bParameter(bParameter),
|
||||||
|
_nominalTemp(nominalTemp),
|
||||||
|
_minTemp(minTemp),
|
||||||
|
_maxTemp(maxTemp),
|
||||||
|
_bufferIndex(0),
|
||||||
|
_bufferFilled(false),
|
||||||
|
_filteredRaw(0),
|
||||||
|
_smoothedRaw(0),
|
||||||
|
_resistance(0),
|
||||||
|
_temperatureC(0)
|
||||||
|
{
|
||||||
|
pinMode(_thermistorPin, INPUT);
|
||||||
|
|
||||||
|
for (int i = 0; i < _bufferSize; i++) {
|
||||||
|
_rawReadings[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThermistorController::update() {
|
||||||
|
float rawValue = analogRead(_thermistorPin);
|
||||||
|
|
||||||
|
_rawReadings[_bufferIndex] = rawValue;
|
||||||
|
|
||||||
|
_bufferIndex = (_bufferIndex + 1) % _bufferSize;
|
||||||
|
if (_bufferIndex == 0) _bufferFilled = true;
|
||||||
|
|
||||||
|
_filteredRaw = applySaltPepperFilter();
|
||||||
|
_smoothedRaw = applyWeightedMovingAverage();
|
||||||
|
_resistance = calculateResistance(_smoothedRaw);
|
||||||
|
_temperatureC = calculateTemperature(_resistance);
|
||||||
|
_temperatureC = applySaturation(_temperatureC, _minTemp, _maxTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare(const void* a, const void* b) {
|
||||||
|
return (*(int*)a - *(int*)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::applySaltPepperFilter() {
|
||||||
|
if (!_bufferFilled) {
|
||||||
|
return _rawReadings[(_bufferIndex - 1 + _bufferSize) % _bufferSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
float sortedValues[_bufferSize];
|
||||||
|
for (int i = 0; i < _bufferSize; i++) {
|
||||||
|
sortedValues[i] = _rawReadings[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(sortedValues, _bufferSize, sizeof(int), compare);
|
||||||
|
|
||||||
|
return sortedValues[_bufferSize / 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::applyWeightedMovingAverage() {
|
||||||
|
if (!_bufferFilled) {
|
||||||
|
return _filteredRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
float weightedSum = 0;
|
||||||
|
float sumOfWeights = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < _bufferSize; i++) {
|
||||||
|
int index = (_bufferIndex - i - 1 + _bufferSize) % _bufferSize;
|
||||||
|
weightedSum += _rawReadings[index] * _weights[i];
|
||||||
|
sumOfWeights += _weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return weightedSum / sumOfWeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::calculateResistance(float adcValue) {
|
||||||
|
return (1023.0 * _seriesResistor) / adcValue - _seriesResistor;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::calculateTemperature(float resistance) {
|
||||||
|
float logR = log(resistance / 10000.0);
|
||||||
|
float temp = (_bParameter / (logR + (_bParameter / (273.15 + _nominalTemp)))) - 273.15;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::applySaturation(float value, float min, float max) {
|
||||||
|
if (value < min) return min;
|
||||||
|
if (value > max) return max;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getRawValue() const {
|
||||||
|
return _rawReadings[(_bufferIndex - 1 + _bufferSize) % _bufferSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getFilteredRaw() const {
|
||||||
|
return _filteredRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getSmoothedRaw() const {
|
||||||
|
return _smoothedRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getResistance() const {
|
||||||
|
return _resistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getTemperatureC() const {
|
||||||
|
return _temperatureC;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ThermistorController::getTemperatureF() const {
|
||||||
|
return _temperatureC * 9.0 / 5.0 + 32.0;
|
||||||
|
}
|
||||||
45
src/labs/Lab2_1.cpp
Normal file
45
src/labs/Lab2_1.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include "labs/Lab2_1.h"
|
||||||
|
|
||||||
|
void TaskOne(bool* state, ButtonController* toggle, LEDController* led) {
|
||||||
|
if (toggle->wasOn()) *state = !*state;
|
||||||
|
led->set(*state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskTwo(bool* toggleState, LEDController* led) {
|
||||||
|
led->tick();
|
||||||
|
led->blink(!*toggleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskThree(int* delayMs, ButtonController* dec, ButtonController* inc, LEDController* led) {
|
||||||
|
*delayMs = dec->wasOn() ? max(200, *delayMs - 200) : inc->wasOn() ? min(4000, *delayMs + 200) : *delayMs;
|
||||||
|
led->interval(*delayMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskIdle(int* lastReportTime, bool* toggleState, int* delayState, LCDController* lcd) {
|
||||||
|
if (millis() - *lastReportTime < 300) return;
|
||||||
|
|
||||||
|
*lastReportTime = millis();
|
||||||
|
lcd->clear();
|
||||||
|
printf("Toggle: %s\nDelay: %d ms", *toggleState ? "ON" : "OFF", *delayState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lab2_1Task(void* pv) {
|
||||||
|
LEDController ledToggle(LED_PIN), ledBlink(LED_BLINK_PIN);
|
||||||
|
LCDController lcd = LCDController(RS, EN, D4, D5, D6, D7);
|
||||||
|
ButtonController tog(BUTTON_TOGGLE_PIN), dec(BUTTON_DECREMENT_PIN), inc(BUTTON_INCREMENT_PIN);
|
||||||
|
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
bool toggleState = false;
|
||||||
|
int delayMs = 1000;
|
||||||
|
int lastReportTime = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
TaskOne(&toggleState, &tog, &ledToggle);
|
||||||
|
TaskTwo(&toggleState, &ledBlink);
|
||||||
|
TaskThree(&delayMs, &dec, &inc, &ledBlink);
|
||||||
|
TaskIdle(&lastReportTime, &toggleState, &delayMs, &lcd);
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/labs/Lab2_2.cpp
Normal file
110
src/labs/Lab2_2.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include "labs/Lab2_2.h"
|
||||||
|
|
||||||
|
void ButtonLedTask(void* parameters) {
|
||||||
|
TaskParameters* params = (TaskParameters*)parameters;
|
||||||
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if (params->button->wasOn()) {
|
||||||
|
params->lcd->clear();
|
||||||
|
params->led->set(true);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
xSemaphoreGive(params->buttonSemaphore);
|
||||||
|
params->led->set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyncTask(void* parameters) {
|
||||||
|
TaskParameters* params = (TaskParameters*)parameters;
|
||||||
|
int N = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if (xSemaphoreTake(params->buttonSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||||
|
N = N + 1;
|
||||||
|
|
||||||
|
for (int i = 1; i <= N; i++) {
|
||||||
|
xQueueSendToFront(params->dataQueue, &i, portMAX_DELAY);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint8_t endMarker = 0;
|
||||||
|
// xQueueSendToFront(params->dataQueue, &endMarker, portMAX_DELAY);
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
params->blinkLed->set(true);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
params->blinkLed->set(false);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncTask(void* parameters) {
|
||||||
|
TaskParameters* params = (TaskParameters*)parameters;
|
||||||
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
|
uint8_t receivedByte;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
while (xQueueReceive(params->dataQueue, &receivedByte, 0) == pdTRUE) {
|
||||||
|
if (receivedByte == 0) {
|
||||||
|
printf("\n");
|
||||||
|
} else {
|
||||||
|
printf("%d", receivedByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Lab2_2Task(void* pv) {
|
||||||
|
LEDController ledButton(LED_BUTTON_PIN), ledBlink(LED_BLINK_PIN);
|
||||||
|
LCDController lcd = LCDController(RS, EN, D4, D5, D6, D7);
|
||||||
|
ButtonController button(BUTTON_PIN);
|
||||||
|
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
SemaphoreHandle_t buttonSemaphore = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
|
QueueHandle_t dataQueue = xQueueCreate(100, sizeof(uint8_t));
|
||||||
|
|
||||||
|
TaskParameters taskParams;
|
||||||
|
taskParams.button = &button;
|
||||||
|
taskParams.led = &ledButton;
|
||||||
|
taskParams.blinkLed = &ledBlink;
|
||||||
|
taskParams.lcd = &lcd;
|
||||||
|
taskParams.buttonSemaphore = buttonSemaphore;
|
||||||
|
taskParams.dataQueue = dataQueue;
|
||||||
|
|
||||||
|
xTaskCreate(
|
||||||
|
ButtonLedTask,
|
||||||
|
"ButtonLed",
|
||||||
|
configMINIMAL_STACK_SIZE,
|
||||||
|
&taskParams,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
xTaskCreate(
|
||||||
|
SyncTask,
|
||||||
|
"Sync",
|
||||||
|
configMINIMAL_STACK_SIZE,
|
||||||
|
&taskParams,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
xTaskCreate(
|
||||||
|
AsyncTask,
|
||||||
|
"Async",
|
||||||
|
configMINIMAL_STACK_SIZE,
|
||||||
|
&taskParams,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
}
|
||||||
176
src/labs/Lab3_1.cpp
Normal file
176
src/labs/Lab3_1.cpp
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#include "labs/Lab3_1.h"
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
|
||||||
|
void Lab3_1Task(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
const char* sensors[] = {
|
||||||
|
" DHT ", " Accltr ", " Light ", " Distance "
|
||||||
|
};
|
||||||
|
const int totalSensors = 4;
|
||||||
|
int currentSensor = 0;
|
||||||
|
|
||||||
|
auto printSelection = [&]() {
|
||||||
|
lcd.clear();
|
||||||
|
printf("Picked:\n<-%s->", sensors[currentSensor]);
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("Choose sensor <>");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
printSelection();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
JoystickDirection dir = joystick.getDirection();
|
||||||
|
|
||||||
|
if (dir == LEFT || dir == RIGHT) {
|
||||||
|
currentSensor = (dir == LEFT) ? (currentSensor + totalSensors - 1) % totalSensors : (currentSensor + 1) % totalSensors;
|
||||||
|
printSelection();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joystick.isPressed()) {
|
||||||
|
lcd.clear();
|
||||||
|
switch (currentSensor) {
|
||||||
|
case 0: xTaskCreate(DHTTask, "DHT", 512, NULL, 1, NULL); break;
|
||||||
|
case 1: xTaskCreate(AccelerometerTask, "Accelerometer", 512, NULL, 1, NULL); break;
|
||||||
|
case 2: xTaskCreate(PhotoresistorTask, "Photoresistor", 512, NULL, 1, NULL); break;
|
||||||
|
case 3: xTaskCreate(DistanceTask, "Distance", 512, NULL, 1, NULL); break;
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHTTask(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
DHTController dht = DHTController(DHT_PIN);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
|
||||||
|
if(joystick.isPressed()) {
|
||||||
|
xTaskCreate(Lab3_1Task, "Lab3_1", 512, NULL, 1, NULL);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
bool success = dht.read();
|
||||||
|
|
||||||
|
float temp = dht.getTemperature();
|
||||||
|
float hum = dht.getHumidity();
|
||||||
|
|
||||||
|
if(success && !isnan(temp) && !isnan(hum)) printf("Temp: %d.%d C\nHumi: %d.%d %%", (int)temp, (int)((temp - (int)temp) * 10), (int)hum, (int)((hum - (int)hum) * 10));
|
||||||
|
else printf("Sensor read\nfailed!");
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccelerometerTask(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
ADXL345Controller accel;
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
accel.begin();
|
||||||
|
accel.setRange(3);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
|
||||||
|
if(joystick.isPressed()) {
|
||||||
|
xTaskCreate(Lab3_1Task, "Lab3_1", 512, NULL, 1, NULL);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
bool success = accel.read();
|
||||||
|
|
||||||
|
double x = accel.getX();
|
||||||
|
double y = accel.getY();
|
||||||
|
double z = accel.getZ();
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
int x_whole = (int)x;
|
||||||
|
int x_dec = abs((int)((x - x_whole) * 100));
|
||||||
|
|
||||||
|
int y_whole = (int)y;
|
||||||
|
int y_dec = abs((int)((y - y_whole) * 100));
|
||||||
|
|
||||||
|
int z_whole = (int)z;
|
||||||
|
int z_dec = abs((int)((z - z_whole) * 100));
|
||||||
|
|
||||||
|
printf("Accelr XYZ:\n%d.%02d %d.%02d %d.%02d", x_whole, x_dec, y_whole, y_dec, z_whole, z_dec);
|
||||||
|
} else printf("Accel read\nfailed!");
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhotoresistorTask(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
PhotoresistorController photoresistor(PHOTORESISTOR_PIN);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
photoresistor.begin();
|
||||||
|
photoresistor.setNumSamples(5);
|
||||||
|
photoresistor.calibrate(100, 900);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
|
||||||
|
if(joystick.isPressed()) {
|
||||||
|
xTaskCreate(Lab3_1Task, "Lab3_1", 512, NULL, 1, NULL);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
bool success = photoresistor.read();
|
||||||
|
|
||||||
|
int rawValue = photoresistor.getRawValue();
|
||||||
|
int percentValue = photoresistor.getPercentValue();
|
||||||
|
|
||||||
|
if(success) printf("Light Level:\nVal:%4d (%3d%%)", rawValue, percentValue);
|
||||||
|
else printf("Sensor read\nfailed!");
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DistanceTask(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
DistanceSensorController distance(TRIG_PIN, ECHO_PIN);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
distance.begin();
|
||||||
|
|
||||||
|
distance.setNumSamples(3);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
|
||||||
|
if(joystick.isPressed()) {
|
||||||
|
xTaskCreate(Lab3_1Task, "Lab3_1", 512, NULL, 1, NULL);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
bool success = distance.read();
|
||||||
|
|
||||||
|
long distanceCm = distance.getDistanceCm();
|
||||||
|
|
||||||
|
if(success) printf("Distance:\n%ld cm", distanceCm);
|
||||||
|
else printf("Sensor read\nfailed!");
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/labs/Lab3_2.cpp
Normal file
36
src/labs/Lab3_2.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "labs/Lab3_2.h"
|
||||||
|
|
||||||
|
void Lab3_2Task(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
|
||||||
|
ThermistorController thermistor(THERMISTOR_PIN, 10000.0, 3435.0, 25.0, -55.0, 125.0);
|
||||||
|
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
const TickType_t xFrequency = pdMS_TO_TICKS(200);
|
||||||
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
thermistor.update();
|
||||||
|
|
||||||
|
float tempC = thermistor.getTemperatureC();
|
||||||
|
float tempF = thermistor.getTemperatureF();
|
||||||
|
float resistance = thermistor.getResistance();
|
||||||
|
|
||||||
|
int tempCInt = (int)tempC;
|
||||||
|
int tempCDec = (int)((tempC - tempCInt) * 10);
|
||||||
|
|
||||||
|
int tempFInt = (int)tempF;
|
||||||
|
int tempFDec = (int)((tempF - tempFInt) * 10);
|
||||||
|
|
||||||
|
int resInt = (int)(resistance / 1000);
|
||||||
|
int resDec = (int)((resistance / 1000.0 - resInt) * 10);
|
||||||
|
|
||||||
|
lcd.clear();
|
||||||
|
printf("Temp: %d.%d C", tempCInt, tempCDec);
|
||||||
|
lcd.setCursor(0, 1);
|
||||||
|
printf("%d.%d F %d.%dk", tempFInt, tempFDec, resInt, resDec);
|
||||||
|
|
||||||
|
vTaskDelayUntil(&xLastWakeTime, xFrequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/labs/Lab4_1.cpp
Normal file
47
src/labs/Lab4_1.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "labs/Lab4_1.h"
|
||||||
|
#include <Arduino_FreeRTOS.h>
|
||||||
|
|
||||||
|
void Lab4_1Task(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
RelayController relay(RELAY_PIN);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
const char* commands[] = {
|
||||||
|
"Turn ON", "Turn OFF"
|
||||||
|
};
|
||||||
|
|
||||||
|
const int totalCommands = 2;
|
||||||
|
int currentCommand = 0;
|
||||||
|
|
||||||
|
auto printSelection = [&]() {
|
||||||
|
lcd.clear();
|
||||||
|
printf("Relay is %s\n%s ->", relay.isConnected() ? "ON" : "OFF", commands[currentCommand]);
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("Pick command <>");
|
||||||
|
while(joystick.isCentered()) joystick.tick();
|
||||||
|
printSelection();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
JoystickDirection dir = joystick.getDirection();
|
||||||
|
|
||||||
|
if (dir == LEFT || dir == RIGHT) {
|
||||||
|
currentCommand = (dir == LEFT) ? (currentCommand + totalCommands - 1) % totalCommands : (currentCommand + 1) % totalCommands;
|
||||||
|
printSelection();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joystick.isPressed()) {
|
||||||
|
lcd.clear();
|
||||||
|
switch (currentCommand) {
|
||||||
|
case 0: relay.connect(); break;
|
||||||
|
case 1: relay.disconnect(); break;
|
||||||
|
}
|
||||||
|
printSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/labs/Lab4_2.cpp
Normal file
74
src/labs/Lab4_2.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#include "labs/Lab4_2.h"
|
||||||
|
|
||||||
|
void Lab4_2Task(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
MotorController motor(MOTOR_PIN_IA, MOTOR_PIN_IB);
|
||||||
|
RelayController relay(RELAY_PIN);
|
||||||
|
relay.connect();
|
||||||
|
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
const char* commands[] = {
|
||||||
|
" set ", " stop ", " max ", " inc ", " dec "
|
||||||
|
};
|
||||||
|
|
||||||
|
const int totalCommands = 5;
|
||||||
|
int currentCommand = 0;
|
||||||
|
|
||||||
|
auto printSelection = [&]() {
|
||||||
|
lcd.clear();
|
||||||
|
printf("Power: %d%% \n%s ->", motor.getPower(), commands[currentCommand]);
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("Motor Control\nUse joystick");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
printSelection();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
JoystickDirection dir = joystick.getDirection();
|
||||||
|
|
||||||
|
if (dir == LEFT || dir == RIGHT) {
|
||||||
|
currentCommand = (dir == LEFT) ?
|
||||||
|
(currentCommand + totalCommands - 1) % totalCommands :
|
||||||
|
(currentCommand + 1) % totalCommands;
|
||||||
|
printSelection();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentCommand == 0 && (dir == UP || dir == DOWN)) {
|
||||||
|
int power = motor.getPower();
|
||||||
|
power = (dir == UP) ? min(100, power + 1) : max(-100, power - 1);
|
||||||
|
motor.set(power);
|
||||||
|
printSelection();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joystick.isPressed()) {
|
||||||
|
lcd.clear();
|
||||||
|
switch (currentCommand) {
|
||||||
|
case 1:
|
||||||
|
motor.stop();
|
||||||
|
printf("Motor stopped");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
motor.maximum();
|
||||||
|
printf("Max power: %d%%", motor.getPower());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
motor.inc();
|
||||||
|
printf("Power inc: %d%%", motor.getPower());
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
motor.dec();
|
||||||
|
printf("Power dec: %d%%", motor.getPower());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
printSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/labs/LabSelector.cpp
Normal file
49
src/labs/LabSelector.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "labs/LabSelector.h"
|
||||||
|
|
||||||
|
void LabSelectorTask(void* pv) {
|
||||||
|
LCDController lcd(RS, EN, D4, D5, D6, D7);
|
||||||
|
JoystickController joystick(VRX, VRY, SW);
|
||||||
|
stdout = lcd.stream();
|
||||||
|
|
||||||
|
const char* labNames[] = {
|
||||||
|
"Lab2.1", "Lab2.2", "Lab3.1",
|
||||||
|
"Lab3.2", "Lab4.1", "Lab4.2"
|
||||||
|
};
|
||||||
|
const int totalLabs = 6;
|
||||||
|
int currentLab = 0;
|
||||||
|
|
||||||
|
auto printSelection = [&]() {
|
||||||
|
lcd.clear();
|
||||||
|
printf("Selected:\n<- %s ->", labNames[currentLab]);
|
||||||
|
};
|
||||||
|
|
||||||
|
printf("Lab Picker\nUse joystick <>");
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
|
printSelection();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
joystick.tick();
|
||||||
|
JoystickDirection dir = joystick.getDirection();
|
||||||
|
|
||||||
|
if (dir == LEFT || dir == RIGHT) {
|
||||||
|
currentLab = (dir == LEFT) ? (currentLab + totalLabs - 1) % totalLabs : (currentLab + 1) % totalLabs;
|
||||||
|
printSelection();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joystick.isPressed()) {
|
||||||
|
lcd.clear();
|
||||||
|
switch (currentLab) {
|
||||||
|
case 0: xTaskCreate(Lab2_1Task, "Lab2_1", 512, NULL, 1, NULL); break;
|
||||||
|
case 1: xTaskCreate(Lab2_2Task, "Lab2_2", 512, NULL, 1, NULL); break;
|
||||||
|
case 2: xTaskCreate(Lab3_1Task, "Lab3_1", 512, NULL, 1, NULL); break;
|
||||||
|
case 3: xTaskCreate(Lab3_2Task, "Lab3_2", 512, NULL, 1, NULL); break;
|
||||||
|
case 4: xTaskCreate(Lab4_1Task, "Lab4_1", 512, NULL, 1, NULL); break;
|
||||||
|
case 5: xTaskCreate(Lab4_2Task, "Lab4_2", 512, NULL, 1, NULL); break;
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/main.cpp
Normal file
14
src/main.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "labs/LabSelector.h"
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
xTaskCreate(
|
||||||
|
LabSelectorTask,
|
||||||
|
"LabPicker",
|
||||||
|
512,
|
||||||
|
NULL,
|
||||||
|
1,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
11
test/README
Normal file
11
test/README
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
This directory is intended for PlatformIO Test Runner and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PlatformIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||||
Reference in New Issue
Block a user