restructured
This commit is contained in:
parent
2f7d1dd921
commit
91e1a7d424
12 changed files with 33 additions and 28 deletions
31
src/CMakeLists.txt
Normal file
31
src/CMakeLists.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
configure_file(config.h.in ${PROJECT_BINARY_DIR}/src/config.h)
|
||||
|
||||
set(SOURCES
|
||||
gbmanager.cpp
|
||||
lcd.cpp
|
||||
ds18b20.cpp
|
||||
relais.cpp
|
||||
)
|
||||
|
||||
# Add executable. Default name is the project name, version 0.1
|
||||
add_executable(gbmanager ${SOURCES})
|
||||
|
||||
pico_set_program_name(gbmanager "gbmanager")
|
||||
pico_set_program_version(gbmanager ${PROJECT_VERSION})
|
||||
|
||||
pico_enable_stdio_uart(gbmanager 1)
|
||||
pico_enable_stdio_usb(gbmanager 0)
|
||||
|
||||
pico_generate_pio_header(gbmanager ${CMAKE_CURRENT_LIST_DIR}/ds18b20.pio)
|
||||
|
||||
# Add the standard library to the build
|
||||
target_link_libraries(gbmanager pico_stdlib)
|
||||
|
||||
# Add any user requested libraries
|
||||
target_link_libraries(gbmanager
|
||||
hardware_i2c
|
||||
hardware_gpio
|
||||
hardware_pio
|
||||
)
|
||||
|
||||
pico_add_extra_outputs(gbmanager)
|
6
src/config.h.in
Normal file
6
src/config.h.in
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#cmakedefine PROJECT_VERSION "@PROJECT_VERSION@"
|
||||
|
||||
#endif
|
72
src/ds18b20.cpp
Normal file
72
src/ds18b20.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "ds18b20.h"
|
||||
|
||||
DS18B20::DS18B20(PIO pio, uint8_t gpio) : pio{pio}, gpio{gpio} {
|
||||
uint offset = pio_add_program(pio, &ds18b20_program);
|
||||
stateMachineIndex = pio_claim_unused_sm(pio, true);
|
||||
pio_gpio_init(pio, gpio);
|
||||
pio_sm_config c = ds18b20_program_get_default_config(offset);
|
||||
sm_config_set_clkdiv_int_frac(&c, 255, 0);
|
||||
sm_config_set_set_pins(&c, gpio, 1);
|
||||
sm_config_set_out_pins(&c, gpio, 1);
|
||||
sm_config_set_in_pins(&c, gpio);
|
||||
sm_config_set_in_shift(&c, true, true, 8);
|
||||
pio_sm_init(pio0, stateMachineIndex, offset, &c);
|
||||
pio_sm_set_enabled(pio0, stateMachineIndex, true);
|
||||
}
|
||||
|
||||
void DS18B20::writeBytes(uint8_t bytes[], int len) {
|
||||
pio_sm_put_blocking(pio, stateMachineIndex, 250);
|
||||
pio_sm_put_blocking(pio, stateMachineIndex, len - 1);
|
||||
for (int i = 0; i < len; i++) {
|
||||
pio_sm_put_blocking(pio, stateMachineIndex, bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void DS18B20::readBytes(uint8_t bytes[], int len) {
|
||||
pio_sm_put_blocking(pio, stateMachineIndex, 0);
|
||||
pio_sm_put_blocking(pio, stateMachineIndex, len - 1);
|
||||
for (int i = 0; i < len; i++) {
|
||||
bytes[i] = pio_sm_get_blocking(pio, stateMachineIndex) >> 24;
|
||||
}
|
||||
}
|
||||
|
||||
void DS18B20::convert() {
|
||||
uint8_t d[2] = {0xCC, 0x44};
|
||||
writeBytes(d, 2);
|
||||
}
|
||||
|
||||
uint8_t DS18B20::crc8(uint8_t *data, uint8_t len) {
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
uint8_t temp;
|
||||
uint8_t databyte;
|
||||
uint8_t crc = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
databyte = data[i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
temp = (crc ^ databyte) & 0x01;
|
||||
crc >>= 1;
|
||||
if (temp)
|
||||
crc ^= 0x8C;
|
||||
databyte >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
float DS18B20::getTemperature() {
|
||||
uint8_t d[2] = {0xCC, 0xBE};
|
||||
writeBytes(d, 2);
|
||||
uint8_t data[9];
|
||||
readBytes(data, 9);
|
||||
uint8_t crc = crc8(data, 9);
|
||||
if (crc != 0)
|
||||
return -2000;
|
||||
int t1 = data[0];
|
||||
int t2 = data[1];
|
||||
int16_t temp1 = (t2 << 8 | t1);
|
||||
volatile float temp = (float)temp1 / 16;
|
||||
return temp;
|
||||
}
|
23
src/ds18b20.h
Normal file
23
src/ds18b20.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef DS18B20_H
|
||||
#define DS18B20_H
|
||||
|
||||
#include "ds18b20.pio.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
class DS18B20 {
|
||||
public:
|
||||
DS18B20(PIO pio, uint8_t gpio);
|
||||
float getTemperature();
|
||||
void convert();
|
||||
|
||||
private:
|
||||
uint8_t crc8(uint8_t *data, uint8_t len);
|
||||
void writeBytes(uint8_t bytes[], int len);
|
||||
void readBytes(uint8_t bytes[], int len);
|
||||
PIO pio;
|
||||
uint8_t gpio;
|
||||
uint stateMachineIndex;
|
||||
};
|
||||
|
||||
#endif
|
44
src/ds18b20.pio
Normal file
44
src/ds18b20.pio
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
.program ds18b20
|
||||
.wrap_target
|
||||
again:
|
||||
pull block
|
||||
mov x, osr
|
||||
jmp !x, read
|
||||
|
||||
write: set pindirs, 1
|
||||
set pins, 0
|
||||
loop1:
|
||||
jmp x--,loop1
|
||||
set pindirs, 0 [31]
|
||||
wait 1 pin 0 [31]
|
||||
|
||||
pull block
|
||||
mov x, osr
|
||||
bytes1:
|
||||
pull block
|
||||
set y, 7
|
||||
set pindirs, 1
|
||||
bit1:
|
||||
set pins, 0 [1]
|
||||
out pins,1 [31]
|
||||
set pins, 1 [20]
|
||||
jmp y--,bit1
|
||||
jmp x--,bytes1
|
||||
|
||||
set pindirs, 0 [31]
|
||||
jmp again
|
||||
|
||||
read:
|
||||
pull block
|
||||
mov x, osr
|
||||
bytes2:
|
||||
set y, 7
|
||||
bit2:
|
||||
set pindirs, 1
|
||||
set pins, 0 [1]
|
||||
set pindirs, 0 [5]
|
||||
in pins,1 [10]
|
||||
jmp y--,bit2
|
||||
jmp x--,bytes2
|
||||
.wrap
|
80
src/gbmanager.cpp
Normal file
80
src/gbmanager.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "hardware/i2c.h"
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "ds18b20.h"
|
||||
#include "lcd.h"
|
||||
#include "relais.h"
|
||||
|
||||
// GPIOs used
|
||||
constexpr uint I2C_SDA_PIN = 26;
|
||||
constexpr uint I2C_SCL_PIN = 27;
|
||||
constexpr uint DS18B20_PIN = 28;
|
||||
constexpr uint RELAIS_PIN = 18;
|
||||
|
||||
// Custom chars for the LCD
|
||||
constexpr char CUSTOM_CHAR_DEG = 0xDF;
|
||||
constexpr char CUSTOM_CHAR_AE = 0xE1;
|
||||
|
||||
using std::string;
|
||||
|
||||
int main() {
|
||||
// Enable UART so we can print status output
|
||||
stdio_init_all();
|
||||
|
||||
// Initialize the LCD
|
||||
auto myLCD = LCD(i2c1, I2C_SDA_PIN, I2C_SCL_PIN);
|
||||
myLCD.clear();
|
||||
|
||||
// Initialize the temp sensor
|
||||
// DS18B20 ds = DS18B20(pio0, DS18B20_PIN);
|
||||
|
||||
// Initialize the relais
|
||||
Relais relais(RELAIS_PIN);
|
||||
|
||||
float temp_act{0};
|
||||
float temp_tgt{28.0};
|
||||
float temp_diff{0.5};
|
||||
std::stringstream lcdText{};
|
||||
bool isHeating = false;
|
||||
bool isSystemOn = false;
|
||||
string heatInfo{" "};
|
||||
string systemInfo{"OFF"};
|
||||
|
||||
lcdText << " G" << CUSTOM_CHAR_AE << "rbox Manager\n (Ver. "
|
||||
<< PROJECT_VERSION << ")";
|
||||
myLCD.sendString(lcdText.str());
|
||||
sleep_ms(3000);
|
||||
|
||||
while (true) {
|
||||
// ds.convert();
|
||||
sleep_ms(750);
|
||||
// temp_act = ds.getTemperature();
|
||||
temp_act = 23.5;
|
||||
|
||||
if (isSystemOn && temp_act < temp_tgt - temp_diff) {
|
||||
isHeating = true;
|
||||
} else if (isSystemOn && temp_act > temp_tgt + temp_diff) {
|
||||
isHeating = false;
|
||||
} else if (!isSystemOn) {
|
||||
isHeating = false;
|
||||
}
|
||||
isHeating ? heatInfo = ">H<" : heatInfo = " ";
|
||||
|
||||
relais.activate(isHeating);
|
||||
|
||||
lcdText.str("");
|
||||
lcdText.clear();
|
||||
lcdText.precision(4);
|
||||
lcdText << "ACT: " << temp_act << CUSTOM_CHAR_DEG << "C " << heatInfo
|
||||
<< "\n"
|
||||
<< "TGT: " << temp_tgt << CUSTOM_CHAR_DEG << "C " << systemInfo;
|
||||
|
||||
myLCD.setCursor(0, 0);
|
||||
myLCD.sendString(lcdText.str());
|
||||
}
|
||||
}
|
98
src/lcd.cpp
Normal file
98
src/lcd.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include "lcd.h"
|
||||
|
||||
// commands
|
||||
constexpr int LCD_CLEARDISPLAY = 0x01;
|
||||
constexpr int LCD_RETURNHOME = 0x02;
|
||||
constexpr int LCD_ENTRYMODESET = 0x04;
|
||||
constexpr int LCD_DISPLAYCONTROL = 0x08;
|
||||
constexpr int LCD_CURSORSHIFT = 0x10;
|
||||
constexpr int LCD_FUNCTIONSET = 0x20;
|
||||
constexpr int LCD_SETCGRAMADDR = 0x40;
|
||||
constexpr int LCD_SETDDRAMADDR = 0x80;
|
||||
|
||||
// flags for display entry mode
|
||||
constexpr int LCD_ENTRYSHIFTINCREMENT = 0x01;
|
||||
constexpr int LCD_ENTRYLEFT = 0x02;
|
||||
|
||||
// flags for display and cursor control
|
||||
constexpr int LCD_BLINKON = 0x01;
|
||||
constexpr int LCD_CURSORON = 0x02;
|
||||
constexpr int LCD_DISPLAYON = 0x04;
|
||||
|
||||
// flags for function set
|
||||
constexpr int LCD_5x10DOTS = 0x04;
|
||||
constexpr int LCD_2LINE = 0x08;
|
||||
constexpr int LCD_8BITMODE = 0x10;
|
||||
|
||||
constexpr int LCD_BACKLIGHT = 0x08;
|
||||
constexpr int LCD_ENABLE_BIT = 0x04;
|
||||
|
||||
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)
|
||||
: i2c{i2c}, i2c_addr{i2c_addr}, num_cols{num_cols}, num_lines{num_lines} {
|
||||
i2c_init(i2c1, 100 * 1000);
|
||||
gpio_set_function(gpio_sda, GPIO_FUNC_I2C);
|
||||
gpio_set_function(gpio_scl, GPIO_FUNC_I2C);
|
||||
gpio_pull_up(gpio_sda);
|
||||
gpio_pull_up(gpio_scl);
|
||||
|
||||
sendByte(0x03, Mode::COMMAND);
|
||||
sendByte(0x03, Mode::COMMAND);
|
||||
sendByte(0x03, Mode::COMMAND);
|
||||
sendByte(0x02, Mode::COMMAND);
|
||||
|
||||
sendByte(LCD_ENTRYMODESET | LCD_ENTRYLEFT, Mode::COMMAND);
|
||||
sendByte(LCD_FUNCTIONSET | LCD_2LINE, Mode::COMMAND);
|
||||
sendByte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, Mode::COMMAND);
|
||||
clear();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (c == '\n') {
|
||||
cursor_y++;
|
||||
setCursor(cursor_y, 0);
|
||||
} else {
|
||||
sendChar(c);
|
||||
cursor_x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LCD::clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); }
|
||||
|
||||
void LCD::i2cWriteByte(uint8_t val) {
|
||||
i2c_write_blocking(i2c, i2c_addr, &val, 1, false);
|
||||
}
|
||||
|
||||
void LCD::toggleEnable(uint8_t val) {
|
||||
// Toggle enable pin on LCD display
|
||||
// We cannot do this too quickly or things don't work
|
||||
constexpr uint64_t DELAY_US = 600;
|
||||
sleep_us(DELAY_US);
|
||||
i2cWriteByte(val | LCD_ENABLE_BIT);
|
||||
sleep_us(DELAY_US);
|
||||
i2cWriteByte(val & ~LCD_ENABLE_BIT);
|
||||
sleep_us(DELAY_US);
|
||||
}
|
||||
|
||||
// The display is sent a byte as two separate nibble transfers
|
||||
void LCD::sendByte(uint8_t val, Mode mode) {
|
||||
uint8_t high = static_cast<int>(mode) | (val & 0xF0) | LCD_BACKLIGHT;
|
||||
uint8_t low = static_cast<int>(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT;
|
||||
|
||||
i2cWriteByte(high);
|
||||
toggleEnable(high);
|
||||
i2cWriteByte(low);
|
||||
toggleEnable(low);
|
||||
}
|
34
src/lcd.h
Normal file
34
src/lcd.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef LCD_H
|
||||
#define LCD_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "hardware/i2c.h"
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
enum class Mode { COMMAND, CHARACTER };
|
||||
|
||||
class LCD {
|
||||
public:
|
||||
LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl,
|
||||
const uint8_t i2c_addr = 0x27, uint8_t num_cols = 16,
|
||||
uint8_t num_lines = 2);
|
||||
|
||||
void sendString(const std::string &str);
|
||||
void setCursor(int line, int position);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
void sendByte(uint8_t val, Mode mode);
|
||||
void toggleEnable(uint8_t val);
|
||||
void i2cWriteByte(uint8_t val);
|
||||
void sendChar(char val);
|
||||
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};
|
||||
};
|
||||
|
||||
#endif
|
19
src/relais.cpp
Normal file
19
src/relais.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "relais.h"
|
||||
|
||||
Relais::Relais(uint gpio) : gpio{gpio} {
|
||||
gpio_set_dir(gpio, true);
|
||||
gpio_init(gpio);
|
||||
off();
|
||||
}
|
||||
|
||||
void Relais::activate(bool active) {
|
||||
if (active) {
|
||||
gpio_pull_down(gpio);
|
||||
} else {
|
||||
gpio_pull_up(gpio);
|
||||
}
|
||||
}
|
||||
|
||||
void Relais::on() { activate(true); }
|
||||
|
||||
void Relais::off() { activate(false); }
|
18
src/relais.h
Normal file
18
src/relais.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef RELAIS_H
|
||||
#define RELAIS_H
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
class Relais {
|
||||
public:
|
||||
Relais(uint gpio);
|
||||
void activate(bool active);
|
||||
void on();
|
||||
void off();
|
||||
|
||||
private:
|
||||
uint gpio;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue