Compare commits

..

No commits in common. "9b2e72968383562b4c260231d0c84297cd5997ff" and "c5521a08fa9109586841f7229fa82a89f6c60952" have entirely different histories.

10 changed files with 51 additions and 152 deletions

View File

@ -1,5 +1,4 @@
#include "command-handler.h"
#include "fan-speed.h"
// Initialize empty, global command context
volatile command_context_t context = {UNKNOWN_COMMAND, SRC_NONE, FAN_NONE,
@ -127,7 +126,7 @@ void parse_command(uint8_t command[], uint8_t command_len) {
}
// Store the parameter
param = command[1];
param = command[2];
context.conf = param;
@ -149,8 +148,8 @@ void parse_command(uint8_t command[], uint8_t command_len) {
uint8_t bytes[2];
} config_value;
config_value.bytes[0] = command[2];
config_value.bytes[1] = command[3];
config_value.bytes[0] = command[3];
config_value.bytes[1] = command[4];
// Store the value
context.conf_val = config_value.value;
@ -169,10 +168,6 @@ uint8_t route_command(int pos) {
// Set the flag to store it in the EEPROM
store_config = true;
return 0;
break;
case CNF_NONE:
return 0;
break;
}
break;
@ -202,9 +197,6 @@ uint8_t route_command(int pos) {
case READ_VOLTAGE:
{
// Validate that pos is within range
if (pos >= 2) { return 0; }
// Create a union to store the data
union {
int16_t v;
@ -228,7 +220,7 @@ uint8_t route_command(int pos) {
}
// Send the data
return voltage.bytes[1-pos];
return voltage.bytes[pos];
}
case READ_TERMPERATURE:
{
@ -242,51 +234,19 @@ uint8_t route_command(int pos) {
}
break;
case READ_FAN_SPEED:
// Validate that pos is within range
if (pos >= 2) { return 0; }
// Union to hold the u16
if (context.fan == FAN1) {
union {
uint16_t val;
uint8_t bytes[2];
} speed;
speed.val = fan1_history[fan1_history_index];
return speed.bytes[1-pos];
return fan1_history[0];
} else if (context.fan == FAN2) {
union {
uint16_t val;
uint8_t bytes[2];
} speed;
speed.val = fan2_history[fan2_history_index];
return speed.bytes[1-pos];
return fan2_history[0];
} else {
return 0;
}
break;
case READ_BULK_FAN_SPEED:
if (context.fan == FAN1) {
// Validate that pos is valid, if not return 0
if (pos >= 512) { return 0; }
// Calculate the index position
int16_t index = fan1_history_index - pos;
if (index < 0) { index = 511-pos; }
return fan1_history[index];
return fan1_history[pos];
} else if (context.fan == FAN2) {
// Validate that pos is valid, if not return 0
if (pos >= 512) { return 0; }
// Calculate the index position
int16_t index = fan2_history_index - pos;
if (index < 0) { index = 511-pos; }
return fan2_history[index];
return fan2_history[pos];
} else {
return 0;
}
@ -298,7 +258,6 @@ uint8_t route_command(int pos) {
} else if (context.fan == FAN2) {
memset(fan2_history, 0, sizeof(fan2_history));
}
return 0;
break;
case UNKNOWN_COMMAND:
default:

View File

@ -66,9 +66,6 @@ typedef struct {
// Fan history variables
extern volatile uint16_t fan1_history[512];
extern volatile uint16_t fan2_history[512];
// Fan history index variable
extern volatile uint16_t fan1_history_index;
extern volatile uint16_t fan2_history_index;
// Config
extern volatile config_t config;

View File

@ -1,7 +1,7 @@
#include "fan-speed.h"
#include "fan_speeeed.h"
#include "uart.h"
uint16_t timer_period_ms = 1000;
uint16_t timer_period_ms = 1;
uint16_t fan_speed = 0;
volatile uint16_t fan1_edge_counter = 0;
volatile uint16_t fan2_edge_counter = 0;
@ -10,21 +10,18 @@ volatile uint16_t fan2_edge_counter = 0;
void init_TCA0() {
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm ;
TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm | TCA_SINGLE_CLKSEL_DIV1024_gc ; /* Sysclk /1024 */
TCA0_update_period(timer_period_ms);
}
void TCA0_update_period(uint16_t period_ms) {
float period_s = period_ms / 1E3; // Convert the ms to s
float frequency = 1/ period_s; // convert the period to a frequency
float perbuf_val = frequency * F_CPU / 1024; // F_IQR * F_CPU / TCA_prescaler
TCA0.SINGLE.PERBUF = (uint16_t)perbuf_val;
timer_period_ms = period_ms;
void TCA0_update_period(uint16_t timer_period) {
TCA0.SINGLE.PERBUF = (F_CPU * (1 / timer_period) / 1024); /* F_CPU * F_IRQ / TCA_prescaler */
}
// COUNTINGS / TIME = FREQUENCY
// FREQ / 2 = GIVES ACTUAL FREQ
// FREQ * SEC-IN-A-MINUTE(60) / FAN-BLADES
uint16_t RPM_calculation(uint16_t edge_counter, uint16_t time_ms) {
fan_speed = (edge_counter / (float)((float)time_ms/1000.0) );
fan_speed = (edge_counter / time_ms);
fan_speed = fan_speed/2;
fan_speed = fan_speed * 60/5;
edge_counter = 0;
@ -101,25 +98,8 @@ ISR(AC1_AC_vect){ // AC1 vec flag
// TIMER INTERUPT
ISR (TCA0_OVF_vect) {
cli();
// Increment the index, or reset if it is at the top
if (fan1_history_index < 512) {
fan1_history_index++;
} else {
fan1_history_index = 0;
}
if (fan2_history_index < 512) {
fan2_history_index++;
} else {
fan2_history_index = 0;
}
// Calculate the fanspeed
fan1_history[fan1_history_index] = RPM_calculation(fan1_edge_counter, timer_period_ms);
fan2_history[fan2_history_index] = RPM_calculation(fan2_edge_counter, timer_period_ms);
// Reset the edge counter
RPM_calculation(fan1_edge_counter,timer_period_ms);
RPM_calculation(fan2_edge_counter,timer_period_ms);
fan1_edge_counter = 0;
fan2_edge_counter = 0;
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm ;

View File

@ -29,14 +29,6 @@ extern "C" {
* and inspiration form practice 6 for TCA0 setup
*/
// Fan history variables
extern volatile uint16_t fan1_history[512];
extern volatile uint16_t fan2_history[512];
// Fan history index variable
extern volatile uint16_t fan1_history_index;
extern volatile uint16_t fan2_history_index;
// INITALICE TIMER COUNTER
void init_TCA0();

View File

@ -14,6 +14,7 @@ extern "C" {
// Include the IO for I2C
#include "command-handler.h"
#include "uart.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdbool.h>

View File

@ -4,39 +4,28 @@
*
* Created on March 6, 2024, 12:34 PM
*/
#define F_CPU 4E6
// Include AVR specific libs
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
// Include standard C libraries
#include "uart.h"
#include "voltage.h"
#include <stdbool.h>
#define RTC_PERIOD (511)
#define DELAY_TIME 1000
#include "eeprom.h"
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
// Include custom source files
#include "eeprom.h"
#include "voltage.h"
#define F_CPU 4E6
#include "command-handler.h"
#include "i2c.h"
#include "themistor-temp.h"
#include "fan-speed.h"
// Only enable UART when required for debugging
#ifdef ENABLE_UART
#include "uart.h"
#endif
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
// Fan history variables
volatile uint16_t fan1_history[512] = {0};
volatile uint16_t fan2_history[512] = {0};
// Fan history index variable
volatile uint16_t fan1_history_index = 0;
volatile uint16_t fan2_history_index = 0;
// Default config is 500ms sample rate
volatile config_t config = {500};
@ -44,40 +33,24 @@ volatile bool store_config = false;
int main() {
// Initialize functionality
ADC0_init();
init_alarm_gpio();
init_i2c();
// Fanspeed
init_AC0();
init_AC1();
init_TCA0();
TCA0_update_period(config.ms_fanspeed_sample_rate);
// Only enable UART when required for debugging
#ifdef ENABLE_UART
init_uart((uint16_t)9600);
ADC0_init();
init_led();
init_i2c();
stdout = &USART_stream;
#endif
// Read the stored config struct
config = read_struct_from_EEPROM();
// Enable interrupts
PORTB.DIRSET = PIN3_bm;
sei();
while (1) {
// If we have made a config change, store it and recalculate the period.
// If we have made a config change, store it.
if (store_config) {
TCA0_update_period(config.ms_fanspeed_sample_rate);
write_struct_from_EEPROM(config);
store_config = false;
}
}
// Check the temperature, and start the alarm if required
uint16_t thermistor_voltage = thermistor_voltage_read();
float temperature = calculate_thermistor_temp(thermistor_voltage);
bool start_alarm = voltage_threshold_bool(temperature, 40);
alert_voltage_threshold_exceeded(start_alarm);
}

View File

@ -6,11 +6,11 @@
projectFiles="true">
<itemPath>uart.h</itemPath>
<itemPath>voltage.h</itemPath>
<itemPath>fan_speeeed.h</itemPath>
<itemPath>themistor-temp.h</itemPath>
<itemPath>command-handler.h</itemPath>
<itemPath>eeprom.h</itemPath>
<itemPath>i2c.h</itemPath>
<itemPath>fan-speed.h</itemPath>
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
@ -28,11 +28,11 @@
<itemPath>main.c</itemPath>
<itemPath>uart.c</itemPath>
<itemPath>voltage.c</itemPath>
<itemPath>fan_speeeed.c</itemPath>
<itemPath>thermistor-temp.c</itemPath>
<itemPath>command-handler.c</itemPath>
<itemPath>i2c.c</itemPath>
<itemPath>eeprom.c</itemPath>
<itemPath>fan-speed.c</itemPath>
</logicalFolder>
</logicalFolder>
<projectmakefile>Makefile</projectmakefile>

View File

@ -19,15 +19,12 @@ extern "C" {
#include <stdint.h>
#include <math.h>
#include <avr/io.h>
#define R_T0 100E3
#define R_T0 10000
#define T_0 298.15
#define B 3950
#define R_1 1000
#define ledpin PIN3_bm
// Takes inn messured value
#define ALERT_PIN PIN3_bm
// Takes inn messured value
// Calculates the temperature in celcius
// Returns the thermistor themperature
@ -39,8 +36,8 @@ bool voltage_threshold_bool(float thermistor_temp, uint8_t max_temp);
void alert_voltage_threshold_exceeded(bool voltage_threshold_bool);
// Initialise alarm GPIO
void init_alarm_gpio();
// Initialise led
void init_led();
#ifdef __cplusplus
}

View File

@ -1,8 +1,8 @@
#include "themistor-temp.h"
void init_alarm_gpio(){
PORTB.DIRSET = ALERT_PIN;
void init_led(){
PORTB.DIRSET = ledpin;
}
// The code is inspired by "Arduino thermistor guide" by valtentina Vogelman, 1 november 2023
@ -14,7 +14,7 @@ float calculate_thermistor_temp(float thermistor_voltage){
float ln;
float T_thermistor;
float V_thermistor;
#define V_TOT 3.3
#define V_TOT 5
// Calculate Voltage over thermistor
V_thermistor = (V_TOT/1024)*thermistor_voltage;
@ -44,9 +44,9 @@ bool voltage_threshold_bool(float thermistor_temp, uint8_t max_temp){
//print if the maximum threshold is exceeded.
void alert_voltage_threshold_exceeded(bool voltage_threshold_bool){
if (voltage_threshold_bool){
//printf("Error: maximum temperature exceeded");
PORTB.OUTSET = ALERT_PIN;
printf("Error: maximum temperature exceeded");
PORTB.OUTSET = ledpin;
} else{
PORTB.OUTCLR = ALERT_PIN;
PORTB.OUTCLR = ledpin;
}
}

View File

@ -3,10 +3,10 @@
void ADC0_init(void) {
/* Initializing ADC0 pin*/
/*Voltage reading on pin pd2*/
PORTD.PIN2CTRL &= ~PORT_ISC_gm;
PORTD.PIN2CTRL |= PORT_ISC_INPUT_DISABLE_gc; /* Disable */
PORTD.PIN2CTRL &= PORT_PULLUPEN_bm;
/*Voltage reading on pin pd6*/
PORTD.PIN6CTRL &= ~PORT_ISC_gm;
PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc; /* Disable */
PORTD.PIN6CTRL &= PORT_PULLUPEN_bm;
/* Thermistor */
PORTD.PIN3CTRL &= ~PORT_ISC_gm;
@ -43,7 +43,7 @@ uint16_t thermistor_voltage_read() {
}
// Gets the value over thermistor
uint16_t external_voltage_read() {
ADC0.MUXPOS = 0x02; // Read PD6
ADC0.MUXPOS = 0x06; // Read PD6
uint16_t adc_val = ADC0_read();
return adc_val;