Compare commits

..

10 commits

11 changed files with 151 additions and 148 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "modules/pico-onewire"] [submodule "modules/pico-onewire"]
path = modules/pico-onewire path = modules/pico-onewire
url = https://github.com/adamboardman/pico-onewire.git url = https://github.com/adamboardman/pico-onewire.git
[submodule "modules/fmt"]
path = modules/fmt
url = https://github.com/fmtlib/fmt.git

16
.vscode/launch.json vendored
View file

@ -11,21 +11,19 @@
"request": "launch", "request": "launch",
"type": "cortex-debug", "type": "cortex-debug",
"servertype": "openocd", "servertype": "openocd",
"gdbPath" : "arm-none-eabi-gdb", "gdbPath": "gdb-multiarch",
"device": "RP2040", "device": "RP2040",
//"showDevDebugOutput": "parsed",
"configFiles": [ "configFiles": [
"interface/picoprobe.cfg", "interface/raspberrypi-swd.cfg",
"target/rp2040.cfg" "target/rp2040.cfg"
], ],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd", "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToEntryPoint": "main", "runToEntryPoint": "main",
// Give restart the same functionality as runToMain // Give restart the same functionality as runToEntryPoint - main
//"postRestartCommands": [ "postRestartCommands": [
// "break main", "break main",
// "continue" "continue"
//], ]
"searchDir": ["${env:HOME}/src/openocd/tcl"],
} }
] ]
} }

10
.vscode/settings.json vendored
View file

@ -14,7 +14,13 @@
"visibility": "hidden" "visibility": "hidden"
}, },
}, },
"cortex-debug.openocdPath": "${env:HOME}/src/openocd/src/openocd",
"cmake.generator": "Unix Makefiles",
"C_Cpp.clang_format_fallbackStyle": "LLVM", "C_Cpp.clang_format_fallbackStyle": "LLVM",
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/*/**": true,
"**/.hg/store/**": true,
".flatpak/**": true,
"_build/**": true
},
} }

View file

@ -1,21 +1,22 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-volatile -fmodules-ts") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-exceptions")
# Initialise pico_sdk from installed location # Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc) # (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/usr/share/pico-sdk") #set(PICO_SDK_PATH "/usr/share/pico-sdk")
# Pull in Raspberry Pi Pico SDK (must be before project) # Pull in Raspberry Pi Pico SDK (must be before project)
include("cmake/pico_sdk_import.cmake") include("cmake/pico_sdk_import.cmake")
project(gbmanager VERSION "1.0.0" LANGUAGES C CXX ASM) project(gbmanager VERSION "1.0.3" LANGUAGES C CXX ASM)
# Initialise the Raspberry Pi Pico SDK # Initialise the Raspberry Pi Pico SDK
pico_sdk_init() pico_sdk_init()
add_subdirectory(modules/pico-onewire) add_subdirectory(modules/pico-onewire)
add_subdirectory(modules/fmt)
add_subdirectory(src) add_subdirectory(src)

1
modules/fmt Submodule

@ -0,0 +1 @@
Subproject commit b6f4ceaed0a0a24ccf575fab6c56dd50ccf6f1a9

@ -1 +1 @@
Subproject commit d5af2a1e1d81c3cb21805e332c8185607ee74b1d Subproject commit 6399467cf7687ecb7f8f4e4923303349e0ecf160

View file

@ -1,12 +1,10 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
#add_compile_options(-fmodules-ts)
set(SOURCES set(SOURCES
gbmanager.cpp
lcd.cpp lcd.cpp
relais.cpp relais.cpp
gbmanager.cpp
) )
# Add executable. Default name is the project name, version 0.1 # Add executable. Default name is the project name, version 0.1
@ -16,15 +14,15 @@ pico_set_program_name(${CMAKE_PROJECT_NAME} "gbmanager")
pico_set_program_version(${CMAKE_PROJECT_NAME} ${PROJECT_VERSION}) pico_set_program_version(${CMAKE_PROJECT_NAME} ${PROJECT_VERSION})
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 1) pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0)
pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 1)
else() else()
pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0)
pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0)
endif() endif()
# Add the standard library to the build # Add the standard library to the build
target_link_libraries(${CMAKE_PROJECT_NAME} pico_stdlib pico_one_wire) target_link_libraries(${CMAKE_PROJECT_NAME} pico_stdlib pico_one_wire fmt::fmt-header-only)
# Add any user requested libraries # Add any user requested libraries
target_link_libraries(${CMAKE_PROJECT_NAME} target_link_libraries(${CMAKE_PROJECT_NAME}

View file

@ -1,14 +1,13 @@
#include <sstream> #include <string>
#include "../modules/fmt/include/fmt/format.h"
#include "../modules/pico-onewire/api/one_wire.h" #include "../modules/pico-onewire/api/one_wire.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "config.h" #include "config.h"
//#include "lcd.h" #include "lcd.h"
#include "relais.h"
import lcd;
import relais;
// GPIOs used // GPIOs used
constexpr uint I2C_SDA_PIN = 26; constexpr uint I2C_SDA_PIN = 26;
@ -32,7 +31,7 @@ using std::string;
void buttonPressedCallback(uint gpio, [[maybe_unused]] uint32_t events) { void buttonPressedCallback(uint gpio, [[maybe_unused]] uint32_t events) {
absolute_time_t now = get_absolute_time(); absolute_time_t now = get_absolute_time();
if (absolute_time_diff_us(lastPressed, now) < 750000) { if (absolute_time_diff_us(lastPressed, now) < 500000) {
return; return;
} else { } else {
lastPressed = now; lastPressed = now;
@ -56,7 +55,7 @@ int main() {
stdio_init_all(); stdio_init_all();
// Initialize the LCD // Initialize the LCD
auto myLCD = LCD(i2c1, I2C_SDA_PIN, I2C_SCL_PIN, 16, 2); auto myLCD = LCD(i2c1, I2C_SDA_PIN, I2C_SCL_PIN);
myLCD.clear(); myLCD.clear();
// Initialize the temp sensor // Initialize the temp sensor
@ -66,7 +65,9 @@ int main() {
oneWire.single_device_read_rom(address); oneWire.single_device_read_rom(address);
// Initialize the relais // Initialize the relais
Relais relais(RELAIS_PIN); // It need the button callback function, since it has to disable the on/off
// button for a short amount of time
Relais relais(RELAIS_PIN, &buttonPressedCallback);
// Initialize the Buttons // Initialize the Buttons
gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_FALL, true, gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_FALL, true,
@ -78,17 +79,19 @@ int main() {
float temp_act{0}; float temp_act{0};
float temp_diff{0.5}; float temp_diff{0.5};
std::stringstream lcdText{}; string lcdText{};
bool isHeating = false; bool isHeating = false;
string heatInfo{""}; string heatInfo{""};
string systemInfo{""}; string systemInfo{""};
lcdText << " G" << CUSTOM_CHAR_AE << "rbox Manager\n (Ver. " lcdText = fmt::format(" G{}rbox Manager\n (Ver. {})", CUSTOM_CHAR_AE,
<< PROJECT_VERSION << ")"; PROJECT_VERSION);
myLCD.sendString(lcdText.str()); myLCD.sendString(lcdText);
sleep_ms(3000); sleep_ms(3000);
while (true) { while (true) {
uint64_t destTime = time_us_64() + 1000000;
oneWire.convert_temperature(address, true, false); oneWire.convert_temperature(address, true, false);
temp_act = oneWire.temperature(address); temp_act = oneWire.temperature(address);
@ -105,14 +108,12 @@ int main() {
relais.activate(isHeating); relais.activate(isHeating);
lcdText.str(""); lcdText = fmt::format("ACT: {:05.2f}{}C {}\nTGT: {:05.2f}{}C {}",
lcdText.clear(); temp_act, CUSTOM_CHAR_DEG, heatInfo, temp_tgt,
lcdText.precision(4); CUSTOM_CHAR_DEG, systemInfo);
lcdText << "ACT: " << temp_act << CUSTOM_CHAR_DEG << "C " << heatInfo
<< "\n"
<< "TGT: " << temp_tgt << CUSTOM_CHAR_DEG << "C " << systemInfo;
myLCD.setCursor(0, 0); myLCD.setCursor(0, 0);
myLCD.sendString(lcdText.str()); myLCD.sendString(lcdText);
sleep_until((absolute_time_t){destTime});
} }
} }

View file

@ -1,12 +1,6 @@
module;
#include <string>
#include "hardware/i2c.h"
#include "pico/binary_info.h" #include "pico/binary_info.h"
#include "pico/stdlib.h"
export module lcd; #include "lcd.h"
// commands // commands
constexpr int LCD_CLEARDISPLAY = 0x01; constexpr int LCD_CLEARDISPLAY = 0x01;
@ -35,15 +29,9 @@ constexpr int LCD_8BITMODE = 0x10;
constexpr int LCD_BACKLIGHT = 0x08; constexpr int LCD_BACKLIGHT = 0x08;
constexpr int LCD_ENABLE_BIT = 0x04; constexpr int LCD_ENABLE_BIT = 0x04;
enum class Mode { COMMAND, CHARACTER }; LCD::LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl,
const uint8_t i2c_addr, uint8_t num_cols, uint8_t num_lines)
export class LCD { : i2c{i2c}, i2c_addr{i2c_addr}, num_cols{num_cols}, num_lines{num_lines} {
public:
LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl,
const uint8_t i2c_addr, const uint8_t num_cols = 16,
const uint8_t num_lines = 2)
: i2c{i2c}, i2c_addr{i2c_addr}, num_cols{num_cols}, num_lines{
num_lines} {
i2c_init(i2c, 400 * 1000); i2c_init(i2c, 400 * 1000);
gpio_set_function(gpio_sda, GPIO_FUNC_I2C); gpio_set_function(gpio_sda, GPIO_FUNC_I2C);
gpio_set_function(gpio_scl, GPIO_FUNC_I2C); gpio_set_function(gpio_scl, GPIO_FUNC_I2C);
@ -63,7 +51,17 @@ export class LCD {
clear(); clear();
} }
void sendString(const std::string &str) { // Go to location on LCD
void LCD::setCursor(int line, int position) {
int val = (line == 0) ? 0x80 + position : 0xC0 + position;
sendByte(val, Mode::COMMAND);
cursor_x = line;
cursor_y = position;
}
void LCD::sendChar(char val) { sendByte(val, Mode::CHARACTER); }
void LCD::sendString(const std::string &str) {
for (const char &c : str) { for (const char &c : str) {
if (c == '\n') { if (c == '\n') {
cursor_y++; cursor_y++;
@ -75,24 +73,13 @@ export class LCD {
} }
} }
// Go to location on LCD void LCD::clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); }
void setCursor(int line, int position) {
int val = (line == 0) ? 0x80 + position : 0xC0 + position;
sendByte(val, Mode::COMMAND);
cursor_x = line;
cursor_y = position;
}
void clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); } void LCD::i2cWriteByte(uint8_t val) {
private:
void sendChar(char val) { sendByte(val, Mode::CHARACTER); }
void i2cWriteByte(uint8_t val) {
i2c_write_blocking(i2c, i2c_addr, &val, 1, false); i2c_write_blocking(i2c, i2c_addr, &val, 1, false);
} }
void toggleEnable(uint8_t val) { void LCD::toggleEnable(uint8_t val) {
// Toggle enable pin on LCD display // Toggle enable pin on LCD display
// We cannot do this too quickly or things don't work // We cannot do this too quickly or things don't work
constexpr uint64_t DELAY_US = 600; constexpr uint64_t DELAY_US = 600;
@ -104,21 +91,12 @@ export class LCD {
} }
// The display is sent a byte as two separate nibble transfers // The display is sent a byte as two separate nibble transfers
void sendByte(uint8_t val, Mode mode) { void LCD::sendByte(uint8_t val, Mode mode) {
uint8_t high = static_cast<int>(mode) | (val & 0xF0) | LCD_BACKLIGHT; uint8_t high = static_cast<int>(mode) | (val & 0xF0) | LCD_BACKLIGHT;
uint8_t low = uint8_t low = static_cast<int>(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT;
static_cast<int>(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT;
i2cWriteByte(high); i2cWriteByte(high);
toggleEnable(high); toggleEnable(high);
i2cWriteByte(low); i2cWriteByte(low);
toggleEnable(low); toggleEnable(low);
} }
i2c_inst_t *i2c;
uint8_t i2c_addr;
uint8_t num_cols;
uint8_t num_lines;
uint8_t cursor_x{0};
uint8_t cursor_y{0};
};

View file

@ -1,24 +1,35 @@
module; #include "relais.h"
#include "hardware/gpio.h" Relais::Relais(uint gpio, gpio_irq_callback_t callback)
#include "pico/stdlib.h" : gpio{gpio}, callback{callback} {
export module relais;
export class Relais {
public:
Relais(uint gpio) : gpio{gpio} {
gpio_init(gpio); gpio_init(gpio);
gpio_set_dir(gpio, GPIO_OUT); gpio_set_dir(gpio, GPIO_OUT);
off(); off();
} }
void activate(bool active) { gpio_put(gpio, !active); } void Relais::activate(bool active) {
if (active == lastState) {
return;
}
void on() { activate(true); } lastState = active;
void off() { activate(false); } gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_FALL, false,
callback);
gpio_set_irq_enabled_with_callback(BUTTON_2_PIN, GPIO_IRQ_EDGE_FALL, false,
callback);
gpio_set_irq_enabled_with_callback(BUTTON_3_PIN, GPIO_IRQ_EDGE_FALL, false,
callback);
gpio_put(gpio, !active);
sleep_ms(100);
gpio_set_irq_enabled_with_callback(BUTTON_1_PIN, GPIO_IRQ_EDGE_FALL, true,
callback);
gpio_set_irq_enabled_with_callback(BUTTON_2_PIN, GPIO_IRQ_EDGE_FALL, true,
callback);
gpio_set_irq_enabled_with_callback(BUTTON_3_PIN, GPIO_IRQ_EDGE_FALL, true,
callback);
}
private: void Relais::on() { activate(true); }
uint gpio;
}; void Relais::off() { activate(false); }

View file

@ -4,15 +4,21 @@
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "pico/stdlib.h" #include "pico/stdlib.h"
extern const uint BUTTON_1_PIN; // declared in gbmanager.cpp
extern const uint BUTTON_2_PIN; // declared in gbmanager.cpp
extern const uint BUTTON_3_PIN; // declared in gbmanager.cpp
class Relais { class Relais {
public: public:
Relais(uint gpio); Relais(uint gpio, gpio_irq_callback_t callback);
void activate(bool active); void activate(bool active);
void on(); void on();
void off(); void off();
private: private:
uint gpio; uint gpio;
bool lastState;
gpio_irq_callback_t callback;
}; };
#endif #endif