Skip to content

Commit 3dc6a7f

Browse files
committed
Initial
0 parents  commit 3dc6a7f

File tree

65 files changed

+7716
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+7716
-0
lines changed

images/bin2header.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Python program to take any file and output a C header file (suitable
4+
for Arduino use) containing the same binary data that was in the file.
5+
6+
This is particularly useful for embedding .BMP images in sketches for
7+
use with FTOLED.
8+
9+
Formats the binary data nicely so you can read back values by hand if
10+
you ever need to.
11+
12+
** Requirements **
13+
Python 3. You can download it from http://python.org
14+
15+
** Usage **
16+
bin2header.py <input file> [<output file>]
17+
18+
Output file is optional and defaults to the name of the input file,
19+
with the extension changed to .h.
20+
21+
bin2header.py was written by Angus Gratton.
22+
Copyright 2013 Freetronics Pty Ltd.
23+
24+
This program is free software: you can redistribute it and/or modify it under the terms
25+
of the version 3 GNU General Public License as published by the Free Software Foundation.
26+
27+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
28+
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
29+
See the GNU General Public License for more details.
30+
31+
You should have received a copy of the GNU General Public License along with this program.
32+
If not, see <http://www.gnu.org/licenses/>.
33+
34+
"""
35+
import argparse, sys, re, os.path
36+
37+
TEMPLATE = """
38+
// Generated with bin2header.py by Freetronics
39+
// Source file name: %SOURCE%
40+
41+
#include <stdint.h>
42+
43+
#ifdef __AVR__
44+
#define _PGM_ PROGMEM
45+
#else
46+
#define _PGM_
47+
#endif
48+
49+
%WARNING%
50+
51+
static const uint8_t %ITEMNAME%[] _PGM_ = {
52+
%CONTENT%
53+
};
54+
55+
%WARNING_FOOTER%
56+
"""
57+
58+
WARNING_TEMPLATE = """
59+
#ifdef __AVR__
60+
#error The binary content is too large (>=32kb) to hold in a single array when targeting an AVR-based Arduino. This header will work on ARM-based Arduinos (Arduino Due), though.
61+
#else
62+
"""
63+
64+
WARNING_FOOTER = """
65+
#endif
66+
"""
67+
68+
parser = argparse.ArgumentParser(description="Process a binary file")
69+
parser.add_argument('input', type=argparse.FileType('rb'), help="Input binary file")
70+
parser.add_argument('output', type=argparse.FileType('wb'), help="Output binary file", nargs="?")
71+
72+
def bin2header(source, destination):
73+
content = source.read()
74+
source_len = len(content)
75+
as_hex = [ ("0x%02x" % b) for b in content ]
76+
content = ""
77+
offset = 0
78+
for chunk in chunk_by(as_hex, 16):
79+
content += " /* 0x%04x: */ " % offset
80+
content += ", ".join(chunk)
81+
content += ",\n"
82+
offset += 16
83+
output = TEMPLATE
84+
output = output.replace("%CONTENT%", content)
85+
output = output.replace("%SOURCE%", sys.argv[1])
86+
if source_len < 32768:
87+
output = output.replace("%WARNING%", "")
88+
output = output.replace("%WARNING_FOOTER%", "")
89+
else:
90+
output = output.replace("%WARNING%", WARNING_TEMPLATE)
91+
output = output.replace("%WARNING_FOOTER%", WARNING_FOOTER)
92+
print("WARNING: The binary file is too large (%dkb >= 32kb) to be compiled in this way on an AVR-based platform. It will still work on an ARM-based platforms (ie Arduino Due), though."
93+
% (source_len/1024,))
94+
itemname = re.sub(r'[^a-zA-Z0-9]', '_', os.path.splitext(os.path.basename(destination.name))[0])
95+
output = output.replace("%ITEMNAME%", itemname)
96+
destination.write(bytes(output, 'UTF-8'))
97+
98+
def chunk_by(seq, chunk_size):
99+
""" Yield successive chunks of length chunk_size from seq. """
100+
for i in range(0, len(seq), chunk_size):
101+
yield seq[i:i+chunk_size]
102+
103+
104+
if __name__ == "__main__":
105+
args = parser.parse_args()
106+
output = args.output
107+
if output is None:
108+
path = os.path.splitext(args.input.name)[0] + ".h"
109+
output = open(path, "wb")
110+
bin2header(args.input, output)
111+

images/oled7seg-0-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-0-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-1-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-1-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-2-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-2-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-3-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-3-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-4-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-4-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-5-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-5-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-6-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-6-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-7-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-7-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-8-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-8-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-9-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-9-24bit-38x50.bmp

5.72 KB
Binary file not shown.

images/oled7seg-base-24bit-19x25.bmp

1.52 KB
Binary file not shown.

images/oled7seg-base-24bit-38x50.bmp

5.72 KB
Binary file not shown.

include/ArduinoFanControl.h

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef _ARDUINO_FANCONTROL_H
2+
#define _ARDUINO_FANCONTROL_H
3+
4+
#include <TimerOne.h>
5+
#include <TimerThree.h>
6+
#include "FanControl.h"
7+
8+
class ArduinoFanControl : public FanControl
9+
{
10+
public:
11+
// constructors
12+
ArduinoFanControl(const uint8_t fans);
13+
14+
virtual RESULT initialise();
15+
virtual RESULT setPWMForAll(const uint16_t dutyCycle);
16+
virtual RESULT setPWM(const uint8_t fanid, const uint16_t dutyCycle);
17+
virtual RESULT getTachCount(const uint8_t fanid, uint16_t& tachCount);
18+
19+
private:
20+
void measureTach(const uint8_t fanid, unsigned long ms);
21+
float getTach(const uint8_t fanid, unsigned long ms);
22+
23+
uint16_t _pwmPeriod;
24+
25+
// drives PWM PINs
26+
// based on https://github.com/PaulStoffregen/TimerOne/blob/master/config/known_16bit_timers.h
27+
const char PIN_FAN1_T1 = 11; // Timer1
28+
const char PIN_FAN2_T1 = 12; // Timer1
29+
const char PIN_FAN3_T3 = 5; // Timer3
30+
const char PIN_FAN4_T3 = 3; // Timer3
31+
32+
// interrupts for TACH input
33+
// see https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
34+
const char PIN_TACH1 = 21;
35+
const char PIN_TACH2 = 20;
36+
const char PIN_TACH3 = 19;
37+
const char PIN_TACH4 = 18;
38+
39+
};
40+
41+
#endif

include/ErrCodes.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef __ERR_CODES_H
2+
#define __ERR_CODES_H
3+
4+
// err codes
5+
typedef int RESULT;
6+
#define RES_OK 0
7+
8+
// I2C for MAX
9+
#define ERR_BAD_TRANSMISSION -1
10+
#define ERR_BAD_READ -2
11+
#define ERR_BAD_PARAM -3
12+
13+
// DS18B
14+
#define ERR_FAILED_TO_READ_TEMP -10
15+
#define ERR_FAILED_TO_FIND_DEVICE -11
16+
17+
// Ethernet
18+
#define ERR_FAILED_TO_GET_IP_FROM_DHCP -20
19+
#define ERR_NO_ETHERNET_HW -21
20+
#define ERR_NO_CABLE_DETECTED -22
21+
22+
// Fanstate
23+
#define ERR_FAN_NOT_OPERATIONAL -30
24+
#define ERR_FAN_TACH -31
25+
26+
#endif

include/FanControl.h

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef _FAN_CONTROL_H
2+
#define _FAN_CONTROL_H
3+
4+
#include <Arduino.h>
5+
#include <ArduinoLog.h>
6+
#include "ErrCodes.h"
7+
8+
#define MAX_DUTY_CYCLE 100 // %
9+
#define MIN_DUTY_CYCLE 0
10+
11+
// assertions
12+
#define ASSERT_RANGE(var, min, max, msg) if(var<min || var>max) { \
13+
Log.error(F(msg)); \
14+
return ERR_BAD_PARAM; \
15+
}
16+
17+
#define ASSERT_RANGE_DUTY_CYCLE(var) ASSERT_RANGE( \
18+
var, MIN_DUTY_CYCLE, MAX_DUTY_CYCLE, "Duty cycle is out of range")
19+
20+
#define ASSERT_RANGE_FAN_ID(var, fans) ASSERT_RANGE(\
21+
var, 1, fans, "Fanid out of range")
22+
23+
/**
24+
* Abstract base class for all Fan Control.
25+
* Sub types include Arduino and MAX31790 classes.
26+
*/
27+
class FanControl
28+
{
29+
public:
30+
FanControl(const uint8_t fans) :
31+
_fans(fans) {};
32+
33+
virtual RESULT initialise() = 0;
34+
virtual RESULT setPWMForAll(const uint16_t dutyCycle) = 0;
35+
virtual RESULT setPWM(const uint8_t fanid, const uint16_t dutyCycle) = 0;
36+
virtual RESULT getTachCount(const uint8_t fanid, uint16_t& tachCount) = 0;
37+
38+
const uint8_t getFanCount() const {
39+
return _fans;
40+
};
41+
42+
private:
43+
uint8_t _fans; // total number of fans to control
44+
};
45+
46+
#endif

include/MAX31790FanControl.h

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#ifndef _MAX31790_FANCONTROL_H
2+
#define _MAX31790_FANCONTROL_H
3+
4+
#include "FanControl.h"
5+
6+
// registers
7+
#define GLOBAL_CONFIG_REG 0x00
8+
#define PWM_FREQ 0x01
9+
#define FAN_CONFIG(ch) (0x02+(ch-1))
10+
#define FAN_DYNAMICS(ch) (0x08+(ch-1))
11+
12+
#define TACH_COUNT(ch) (0x18+(ch-1)*2)
13+
#define PWM_DUTY_CYCLE(ch) (0x30+(ch-1)*2)
14+
#define PWMOUT_TARGET_DUTY_CYCLE(ch) (0x40+(ch-1)*2)
15+
#define TACH_TARGET(ch) (0x50+(ch-1)*2)
16+
17+
#define MAX_DUTY_CYCLE_SCALE 511 // range is 0-511
18+
19+
/**
20+
* Global Configuration
21+
* I2C watchdog setting
22+
*/
23+
enum I2CWatchDogEnum
24+
{
25+
Disabled = 0,
26+
FiveSec = 1,
27+
TenSec = 2,
28+
ThirtySec = 3
29+
};
30+
31+
enum OscillatorEnum
32+
{
33+
Internal = 0,
34+
External_Crystal = 1
35+
};
36+
37+
struct GlobalConfig
38+
{
39+
GlobalConfig(
40+
bool standBy_Not_Run = 0,
41+
bool not_Bus_Timeout = 0,
42+
OscillatorEnum oscillator = OscillatorEnum::Internal,
43+
I2CWatchDogEnum watchDog = I2CWatchDogEnum::Disabled)
44+
:
45+
standBy_Not_Run(standBy_Not_Run),
46+
normal_Not_Reset(0),
47+
not_Bus_Timeout(not_Bus_Timeout),
48+
oscillator(oscillator),
49+
watchDog(watchDog) {};
50+
51+
bool standBy_Not_Run:1; // 0 = Run - D7
52+
bool normal_Not_Reset:1; // 0 = Normal
53+
bool not_Bus_Timeout:1; // 0 = Enabled
54+
bool reserved:1;
55+
OscillatorEnum oscillator:1;
56+
I2CWatchDogEnum watchDog:2;
57+
bool watchDogStatus:1; // 1 = watchdog fault detected
58+
};
59+
60+
// @TODO:
61+
typedef struct {
62+
63+
} FanConfigStruct;
64+
65+
class MAX31790 : public FanControl
66+
{
67+
public:
68+
69+
// constructors
70+
MAX31790(const uint8_t i2cAddress, const uint8_t fans);
71+
72+
virtual RESULT initialise();
73+
virtual RESULT setPWMForAll(const uint16_t dutyCycle);
74+
virtual RESULT setPWM(const uint8_t fanid, const uint16_t dutyCycle);
75+
virtual RESULT getTachCount(const uint8_t fanid, uint16_t& tachCount);
76+
77+
RESULT getGlobalConfiguration(GlobalConfig& config);
78+
//RESULT setGlobalConfiguration(const GlobalConfig& config);
79+
//RESULT setFanConfigForAll(const FanConfigStruct& config);
80+
81+
// utility to scan for all i2c devices
82+
void scanForI2C();
83+
84+
// accessors
85+
uint8_t getDeviceAddress() {
86+
return _deviceAddress;
87+
};
88+
89+
private:
90+
RESULT readByte(const uint8_t address, uint8_t& result);
91+
RESULT readBytes(const uint8_t address, const uint8_t n, uint8_t* result);
92+
RESULT writeByte(const uint8_t address, const uint8_t byte);
93+
RESULT writeBytes(const uint8_t address, const uint8_t* bytes, const uint8_t nBytes);
94+
95+
uint16_t scaleDutyCycle(const uint16_t dutyCycle) const;
96+
97+
uint8_t _deviceAddress; // device address - note this is 7bit
98+
};
99+
100+
#endif

include/MqttPublisher.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "RackTempController.h"
2+
#include <Ethernet.h>
3+
#include <ArduinoMqttClient.h>
4+
#include <Print.h>
5+
6+
/**
7+
* Wrapper class for MQTT and Logging framework
8+
*/
9+
class MqttPublisher : public Print {
10+
11+
public:
12+
MqttPublisher(EthernetClient& ethClient, const char* clientID, const char* serverIP, const uint16_t port) :
13+
_mqttClient(ethClient),
14+
_clientID(clientID),
15+
_serverIP(serverIP),
16+
_port(port) {};
17+
18+
void initialise();
19+
20+
void publish(RackState_t& rs);
21+
22+
void poll();
23+
24+
/**
25+
* From Print.h
26+
*/
27+
size_t write(uint8_t c);
28+
29+
private:
30+
void sendMessage(const String& topic, const String& msg);
31+
32+
MqttClient _mqttClient;
33+
34+
const String _clientID; // client identifier
35+
const String _serverIP; // mqtt server IP endpoint
36+
const uint16_t _port; // mqtt server port
37+
String _buf; // log buffer
38+
39+
const String topicTempRackTop = "/device/temp/rack/top";
40+
const String topicTempRackBase = "/device/temp/rack/base";
41+
const String topicTempRackAve = "/device/temp/rack/average";
42+
43+
const String topicFanTopLeft = "/device/rack/fan/topleft";
44+
const String topicFanTopRight = "/device/rack/fan/topright";
45+
const String topicFanBaseLeft = "/device/rack/fan/baseleft";
46+
const String topicFanBaseRight = "/device/rack/fan/baseright";
47+
48+
const String topicRackLog = "/device/rack/log";
49+
const String subtopicFanError = "/error";
50+
const String subtopicFanRPM = "/rpm";
51+
};

0 commit comments

Comments
 (0)