diff options
| -rw-r--r-- | src/app/forced-convection/.config | 101 | ||||
| -rw-r--r-- | src/app/forced-convection/Kconfig | 6 | ||||
| -rw-r--r-- | src/app/forced-convection/Makefile.inc | 9 | ||||
| -rw-r--r-- | src/app/forced-convection/main.cc | 169 |
4 files changed, 285 insertions, 0 deletions
diff --git a/src/app/forced-convection/.config b/src/app/forced-convection/.config new file mode 100644 index 0000000..b8305be --- /dev/null +++ b/src/app/forced-convection/.config @@ -0,0 +1,101 @@ +# +# Automatically generated file; DO NOT EDIT. +# Configuration +# + +# +# System +# +CONFIG_loop=y +# CONFIG_wakeup is not set +# CONFIG_aspectc is not set +CONFIG_i2c_freq=100000 +CONFIG_framebuffer=y +# CONFIG_framebuffer_in_text_segment is not set +CONFIG_framebuffer_width=128 +CONFIG_framebuffer_height=32 + +# +# Libraries +# +# CONFIG_lib_inflate is not set +# CONFIG_arch_arduino_nano is not set +CONFIG_arch_arduino_uno=y +# CONFIG_arch_atmega2560 is not set +# CONFIG_arch_blinkenrocket is not set +# CONFIG_arch_infineon_tc299_mock is not set +# CONFIG_arch_infineon_tc397_mock is not set +# CONFIG_arch_lm4f120h5qr_stellaris is not set +# CONFIG_arch_lora32u4ii is not set +# CONFIG_arch_msp430fr5969lp is not set +# CONFIG_arch_msp430fr5994lp is not set +# CONFIG_arch_posix is not set +# CONFIG_arch_rm46l8lp is not set +# CONFIG_arch_stm32f103c8t6 is not set +# CONFIG_arch_stm32f446re_nucleo is not set +# CONFIG_arch_stm32f746zg_nucleo is not set +# CONFIG_arch_stm32h747i_disco is not set +# CONFIG_arch_tc1796_triboard is not set +CONFIG_arch="arduino-uno" + +# +# Arduino Uno Configuration +# +CONFIG_arch_arduino_uno_cpufreq=16000000 +CONFIG_arch_arduino_uno_driver_adc=y +CONFIG_arch_arduino_uno_driver_i2c=y +# CONFIG_arch_arduino_uno_driver_neopixel is not set +# CONFIG_arch_arduino_uno_driver_spi is not set +# CONFIG_arch_arduino_uno_driver_stdin is not set +# CONFIG_arch_arduino_uno_driver_timer is not set +# CONFIG_arch_arduino_uno_driver_dmx is not set +# CONFIG_app_datalogger is not set +CONFIG_app_forced_convection=y +# CONFIG_app_ledblink is not set +# CONFIG_app_lora32u4ii is not set +# CONFIG_app_sdtest is not set +# CONFIG_app_ssd1306_128x32_bad_apple is not set +# CONFIG_app_ssd1306test is not set +CONFIG_app="forced-convection" +CONFIG_meta_driver_adc=y +CONFIG_meta_driver_hardware_i2c=y +CONFIG_meta_driver_i2c=y + +# +# Drivers +# +# CONFIG_driver_ads111x is not set +# CONFIG_driver_am2320 is not set +# CONFIG_driver_bme280 is not set +# CONFIG_driver_bme680 is not set +# CONFIG_driver_ccs811 is not set +# CONFIG_driver_ds2482 is not set +# CONFIG_driver_eeprom24lc64 is not set +# CONFIG_driver_hdc1080 is not set +CONFIG_driver_lm75=y +# CONFIG_driver_max44006 is not set +# CONFIG_driver_max44009 is not set +# CONFIG_driver_mmsimple is not set +# CONFIG_driver_mmsubstate is not set +# CONFIG_driver_mpu9250 is not set +# CONFIG_driver_s5851a is not set +# CONFIG_driver_scd4x is not set +# CONFIG_driver_sen5x is not set +# CONFIG_driver_sen66 is not set +# CONFIG_driver_veml6075 is not set +CONFIG_driver_ssd1306=y +CONFIG_driver_ssd1306_width=128 +CONFIG_driver_ssd1306_height=32 +CONFIG_driver_ssd1306_mode_vertical=y +# CONFIG_driver_ssd1306_mode_horizontal is not set +CONFIG_driver_ssd1306_i2c_name="softi2c" +# CONFIG_driver_tsl2591 is not set +CONFIG_driver_softi2c=y + +# +# SoftI2C Configuration +# +CONFIG_driver_softi2c_scl="a1" +CONFIG_driver_softi2c_sda="a0" +# CONFIG_driver_softi2c_pullup_none is not set +CONFIG_driver_softi2c_pullup_dynamic_internal=y diff --git a/src/app/forced-convection/Kconfig b/src/app/forced-convection/Kconfig new file mode 100644 index 0000000..157728d --- /dev/null +++ b/src/app/forced-convection/Kconfig @@ -0,0 +1,6 @@ +# Copyright 2026 Birte Kristina Friesel +# +# SPDX-License-Identifier: CC0-1.0 + +prompt "Forced Convection" +depends on loop && !wakeup diff --git a/src/app/forced-convection/Makefile.inc b/src/app/forced-convection/Makefile.inc new file mode 100644 index 0000000..538ac69 --- /dev/null +++ b/src/app/forced-convection/Makefile.inc @@ -0,0 +1,9 @@ +# vim:ft=make +# +# Copyright 2026 Birte Kristina Friesel +# +# SPDX-License-Identifier: CC0-1.0 + +ifdef app + loop = 1 +endif diff --git a/src/app/forced-convection/main.cc b/src/app/forced-convection/main.cc new file mode 100644 index 0000000..052e3fc --- /dev/null +++ b/src/app/forced-convection/main.cc @@ -0,0 +1,169 @@ +/* + * Copyright 2026 Birte Kristina Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include "arch.h" +#include "driver/adc.h" +#include "driver/gpio.h" +#include "driver/stdout.h" +#include "driver/i2c.h" +#include "driver/soft_i2c.h" +#include "driver/lm75.h" +#include "driver/ssd1306.h" +#include "lib/pixelfont/pixeloperator_mirrored.h" +#include "object/framebuffer.h" + + +#define shift_ser GPIO::d8 +#define shift_clk GPIO::d4 +#define shift_latch GPIO::d12 +#define shift_en GPIO::d7 + +#define PWM1 OCR2A +#define PWM2 OCR2B +#define PWM3 OCR0A +#define PWM4 OCR0B + +#define PWM1_EN _BV(5) +#define PWM2_EN _BV(3) +#define PWM3_EN _BV(0) +#define PWM4_EN _BV(7) + +unsigned char graph[88]; +unsigned char graph_offset = 0; + +void loop(void) +{ + static int seconds = 0; + static int fan_speed = 0; + gpio.led_on(0); + float temp = lm75.getTemp(); + + if (temp < 25) { + PWM1 = 0; + PWM2 = 0; + PWM3 = 0; + PWM4 = 0; + TCCR0A = 0; + TCCR2A = 0; + TCCR0B = 0; + TCCR2B = 0; + fan_speed = 0; + } + else if (temp >= 30) { + PWM1 = 255; + PWM2 = 255; + PWM3 = 255; + PWM4 = 255; + TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); + TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); + TCCR0B = _BV(CS00); + TCCR2B = _BV(CS20); + fan_speed = 100; + } + + if (seconds++ == 60) { + if (temp < 20) { + graph[graph_offset ] = 0; + } + else if (temp > 40) { + graph[graph_offset ] = 31; + } + else { + graph[graph_offset] = (temp - 20) * 1.5; + } + seconds = 0; + graph_offset = (graph_offset + 1) % (sizeof(graph) / sizeof(graph[0])); + } + + uint16_t vcc = adc.getVCC_mV() - 200; + + fb.clear(); + fb.setFont(pixeloperator_mirrored); + fb.setPos(88, 0); + fb << temp << "c"; + fb.setPos(88, 16); + fb << vcc/1000 << "." << (vcc%1000)/100 << (vcc%100)/10 << "V"; + fb.setPos(88, 24); + fb << fan_speed << "%"; + + for (unsigned char i = 0; i < (sizeof(graph) / sizeof(graph[0])); i++) { + unsigned char column_value = graph[(graph_offset + i) % (sizeof(graph) / sizeof(graph[0]))]; + fb.data[i*4 + 3 - (column_value/8)] = 1 << ( 7 - column_value%8); + } + ssd1306.showImage(fb.data, fb.width * fb.height / 8); + + kout << "temperature_celsius: "; + kout.printf_float(temp); + kout << endl; + gpio.led_off(0); +} + +int main(void) +{ + arch.setup(); + gpio.setup(); + kout.setup(); + + gpio.led_on(0); + + /* + * Ensure that the SSD1306 OLED display gets a clean reset / power cycle + */ + + gpio.output(GPIO::a2, 0); + gpio.output(GPIO::a3, 0); + + arch.delay_ms(50); + + gpio.write(GPIO::a2, 1); + gpio.write(GPIO::a3, 0); + + arch.delay_ms(50); + + if (i2c.setup() != 0) { + kout << "I2C setup FAILED" << endl; + return 1; + } + kout << "I2C setup OK" << endl; + + if (softi2c.setup() != 0) { + kout << "SoftI2C setup FAILED" << endl; + return 1; + } + kout << "SoftI2C setup OK" << endl; + + lm75.setOS(30); + lm75.setHyst(25); + ssd1306.init(); + + fb.setFont(pixeloperator_mirrored); + + gpio.output(shift_ser, 0); + gpio.output(shift_clk, 0); + gpio.output(shift_latch, 0); + gpio.output(shift_en, 0); + + gpio.output(GPIO::pd3, 0); // OC2B - D3 + gpio.output(GPIO::pd5, 0); // OC0B - D5 + gpio.output(GPIO::pd6, 0); // OC0A - D6 + gpio.output(GPIO::pb3, 0); // OC2A - D11 + + // m4a m2a m1a m1b m2b m3a m4b m3b + uint8_t shift_out = 0b10101001; + + for (unsigned int i = 0; i < 8; i++) { + gpio.write(shift_ser, shift_out & (1<<i)); + gpio.write(shift_clk, 1); + gpio.write(shift_clk, 0); + } + gpio.write(shift_latch, 1); + gpio.write(shift_latch, 0); + + gpio.led_off(0); + + arch.idle_loop(); + + return 0; +} |
