first commit

This commit is contained in:
-help 2024-01-26 00:42:39 +02:00
commit 737c6c3b35
10 changed files with 716 additions and 0 deletions

5
.gitignore vendored Normal file
View 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
View 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"
]
}

39
include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

31
platformio.ini Normal file
View File

@ -0,0 +1,31 @@
; 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:ATmega4809]
platform = atmelmegaavr
board = ATmega4809
framework = arduino
upload_speed = 115200
board_hardware.uart = uart0
upload_protocol = arduino
lib_ldf_mode = chain+
; change MCU frequency
board_build.f_cpu = 16000000L
lib_deps =
adafruit/Adafruit GFX Library@^1.11.5
adafruit/Adafruit ST7735 and ST7789 Library@^1.10.0
https://github.com/adafruit/Adafruit_BusIO.git
SPI
Wire
https://github.com/PowerBroker2/ArduPID.git
https://github.com/PowerBroker2/FireTimer.git
https://github.com/adafruit/Adafruit_SSD1306.git

91
src/Tools/AnalogRef.h Normal file
View File

@ -0,0 +1,91 @@
#ifndef ANALOGREF_H
#define ANALOGREF_H
#include <Arduino.h>
class AnalogRef
{
private:
float systemVoltage; // Reference voltage in volts
boolean systemVolatgeBelow4_5V = false;
uint8_t voltageRefPin = 27;
uint8_t voltageInPin = 28;
public:
float sysVoltage;
float sysMultiplyer;
float outputVoltage;
float outputVoltageMultiplyer;
float differenceMultiplyer;
AnalogRef(float systemVoltage)
{
this->systemVoltage = systemVoltage;
}
float calculateSystemVoltage()
{
const uint8_t sampleCount = 1;
uint16_t rawValue = 0;
for (size_t i = 0; i < sampleCount; ++i)
{
rawValue += analogRead(voltageRefPin);
}
const float voltageRef = 1023.0;
const float systemVoltage = 5.0;
const float systemVoltageOut = rawValue / sampleCount * systemVoltage / voltageRef;
const float voltage5V = 2.5 / systemVoltageOut * systemVoltage;
systemVolatgeBelow4_5V = voltage5V < 4.5;
return voltage5V;
}
float calculateSystemVoltageMultyplyer()
{
// Calculate the actual 5V system voltage
float currentSystemVoltage = calculateSystemVoltage();
// Calculate the actual 5V system voltage
float voltage_5V_multiplyer = (5 / currentSystemVoltage);
return voltage_5V_multiplyer;
}
float calculateInputVoltage()
{
calculateSystemVoltage();
float value;
uint8_t sampleCount = 20;
value = 0;
for (size_t i = 0; i < sampleCount; ++i)
{
value += analogRead(voltageInPin);
}
value /= sampleCount;
float vOut = (value * systemVoltage) / 1024.0;
return vOut * 5.8;
}
void calculate()
{
sysVoltage = calculateSystemVoltage();
sysMultiplyer = 5 / sysVoltage;
}
};
#endif // ANALOGREF_H

85
src/Tools/Thermistor.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "Thermistor.h"
Thermistor::Thermistor()
{
}
Thermistor::Thermistor(uint8_t pin, float resistance, TempCalibration calibration)
{
thermistorPin = pin;
setRes = resistance;
calculateCoefficents(resistance, calibration);
}
Thermistor::~Thermistor()
{
}
int Thermistor::getTemperature()
{
// Get an average of 5 readings
int temp = 0;
uint8_t samples = 5;
for (int i = 0; i < samples; i++)
{
getResistance();
temp += (int)1 / (coefficents.a + coefficents.b * log(sensorResistance) + coefficents.c * (pow(log(sensorResistance), 3))) - K;
}
temp = temp / samples;
return temp;
}
void Thermistor::calculateCoefficents(float resistance, TempCalibration calibration)
{
float lowK = calibration.lowC + K;
float midK = calibration.midC + K;
float highK = calibration.highC + K;
float lowLnr = log(calibration.lowR);
float midLnr = log(calibration.midR);
float highLnr = log(calibration.highR);
float ln1 = lowLnr - midLnr;
float ln2 = lowLnr - highLnr;
float t1 = (1 / lowK) - (1 / midK);
float t2 = (1 / lowK) - (1 / highK);
float c = (t1 - ln1 * t2 / ln2) / ((pow(lowLnr, 3) - pow(midLnr, 3)) - ln1 * (pow(lowLnr, 3) - pow(highLnr, 3)) / ln2);
float b = (t1 - c * (pow(lowLnr, 3) - pow(midLnr, 3))) / ln1;
float a = 1 / lowK - c * pow(lowLnr, 3) - b * lowLnr;
coefficents.a = (a);
coefficents.b = (b);
coefficents.c = (c);
}
float Thermistor::getResistance()
{
analogRef.calculate();
float systemVoltage = analogRef.sysVoltage;
int raw = analogRead(thermistorPin);
// Get resistance value
float buffer = raw * systemVoltage;
float vOut = (buffer) / 1023;
// Serial.println(vOut);
buffer = (systemVoltage / vOut) - 1;
// Serial.println(R2);
// return the resistence
sensorResistance = setRes * buffer;
return sensorResistance;
}

73
src/Tools/Thermistor.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef THERMISTOR_H
#define THERMISTOR_H
#include <Arduino.h>
#include <Tools/AnalogRef.h>
#define THERMISTOR1_PIN 39
#define THERMISTOR2_PIN 38
#define THERMISTOR3_PIN 37
#define THERMISTOR4_PIN 36
#define THERMISTOR5_PIN 33
#define THERMISTOR6_PIN 32
extern AnalogRef analogRef;
// Include any necessary libraries here
struct Coefficents
{
float a;
float b;
float c;
};
struct TempCalibration
{
float lowC;
float lowR;
float midC;
float midR;
float highC;
float highR;
};
class Thermistor
{
public:
// Constructor
Thermistor();
Thermistor(uint8_t pin, float resistance, TempCalibration calibration);
// Destructor
~Thermistor();
// Public Methods
int getTemperature();
float getResistance();
// Public Variables
private:
const double K = 273.15;
float sensorResistance;
uint8_t thermistorPin;
float setRes;
Coefficents coefficents;
float referenceResistance;
void calculateCoefficents(float resistance, TempCalibration calibration);
};
#endif // THERMISTOR_H

325
src/main.cpp Normal file
View File

@ -0,0 +1,325 @@
#include <Arduino.h>
#include "ArduPID.h"
#include <Adafruit_ST7789.h> // Include the ST7789 library
#include <Adafruit_GFX.h>
#include <Tools/AnalogRef.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Tools/Thermistor.h>
enum Button
{
UP,
DOWN,
BACK,
SELECT,
NONE
};
AnalogRef analogRef(5.0);
// LED pins
#define yellowLED 18
#define greenLED 19
#define redLED 20
// Button pins
#define upButton 21
#define downButton 22
#define backButton 23
#define selectButton 24
volatile bool upButtonPressed = false;
volatile bool downButtonPressed = false;
volatile bool backButtonPressed = false;
volatile bool selectButtonPressed = false;
volatile bool upButtonReleased = false;
volatile bool downButtonReleased = false;
volatile bool backButtonReleased = false;
volatile bool selectButtonReleased = false;
enum ButtonState
{
IDLE,
PRESSED,
RELEASED
};
ButtonState upButtonState = IDLE;
ButtonState downButtonState = IDLE;
ButtonState backButtonState = IDLE;
ButtonState selectButtonState = IDLE;
// LCD display pins
#define TFT_CS 7
#define TFT_RST 12
#define TFT_DC 14
#define MOSI 4 // MOSI
#define SCK 6 // SCK
// Create an instance of the Adafruit ST7789 class using the custom SPI pins
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST);
// OLED display width and height, for a typical 128x64 display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Initalize a 3950 100K thermistor with 2.5k reference resistor
Thermistor thermistor1(THERMISTOR1_PIN, 2500, {25, 100000, 86, 10000, 170, 1000});
ArduPID PID;
Button getPressedButton();
Button handleButtons();
void upButtonISR();
void downButtonISR();
void backButtonISR();
void selectButtonISR();
void i2cScanner();
void setup()
{
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed further, loop forever
}
analogWriteFrequency(64);
display.setRotation(3);
pinMode(yellowLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(backButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(upButton), upButtonISR, FALLING);
attachInterrupt(digitalPinToInterrupt(downButton), downButtonISR, FALLING);
attachInterrupt(digitalPinToInterrupt(backButton), backButtonISR, FALLING);
attachInterrupt(digitalPinToInterrupt(selectButton), selectButtonISR, FALLING);
Serial.begin(9600);
Serial.println("Starting LCD");
// tft.init(240, 320); // The dimensions (width and height) of your display
// // Set the rotation of the display if needed (0, 1, 2, or 3)
// tft.setRotation(1);
// // Fill the screen with a background color
// tft.fillScreen(ST77XX_BLACK);
// // Draw the lines of the gaph with 20 pixels from left side and 20 pixels from bottom just left side and bottom line using draw fast line
// tft.drawLine(30, 30, 30, 210, ST77XX_WHITE);
// tft.drawLine(30, 210, 300, 210, ST77XX_WHITE);
// Set cursor to middle of screen and calculate center line from text vairable;
// char *text = "Reflow quickchip 138c";
// int16_t x1, y1;
// uint16_t w, h;
// tft.setTextSize(2);
// tft.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
// tft.setCursor(160 - (w / 2), 0 + (h / 2));
// // // Print text to screen
// tft.print(text);
Serial.println("Ready!");
}
void loop()
{
handleButtons();
analogRef.calculate();
float sysVoltage = analogRef.sysVoltage;
float inputVoltage = analogRef.calculateInputVoltage();
// Print the system voltage on the tft
display.clearDisplay();
Serial.print("Thermistor 1: ");
Serial.println(thermistor1.getTemperature());
char *text = "Sys V: ";
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 20);
display.println(text);
display.setCursor(0, 40);
display.println(sysVoltage);
char *text2 = "In V: ";
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 60);
display.println(text2);
display.setCursor(0, 80);
display.println(inputVoltage);
char *text3 = "C:";
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 100);
display.println(text3);
display.setCursor(25, 100);
display.println(thermistor1.getTemperature());
display.display();
// Serial.println("System voltage: ");
// Serial.print("Output voltage: ");
// Serial.println(sysVoltage);
// Serial.print("Input voltage: ");
// Serial.println(analogRef.calculateInputVoltage());
}
Button getPressedButton()
{
if (upButtonPressed)
{
upButtonPressed = false;
return UP;
}
else if (downButtonPressed)
{
downButtonPressed = false;
return DOWN;
}
else if (backButtonPressed)
{
backButtonPressed = false;
return BACK;
}
else if (selectButtonPressed)
{
selectButtonPressed = false;
return SELECT;
}
return NONE;
}
Button handleButtons()
{
Button pressedButton = getPressedButton();
if (pressedButton != NONE)
{
Serial.print("Button pressed: ");
switch (pressedButton)
{
case UP:
Serial.println("UP");
digitalWrite(yellowLED, HIGH);
delay(100);
digitalWrite(yellowLED, LOW);
break;
case DOWN:
Serial.println("DOWN");
digitalWrite(yellowLED, HIGH);
delay(100);
digitalWrite(yellowLED, LOW);
break;
case BACK:
Serial.println("BACK");
digitalWrite(redLED, HIGH);
delay(100);
digitalWrite(redLED, LOW);
break;
case SELECT:
Serial.println("SELECT");
analogWrite(greenLED, 20);
delay(100);
analogWrite(greenLED, 0);
break;
default:
break;
}
}
return pressedButton;
}
void upButtonISR()
{
upButtonPressed = true;
}
void downButtonISR()
{
downButtonPressed = true;
}
void backButtonISR()
{
backButtonPressed = true;
}
void selectButtonISR()
{
selectButtonPressed = true;
}
void i2cScanner()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++)
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
}
else if (error == 4)
{
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}

11
test/README Normal file
View 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