Skip to content

Commit dbe63db

Browse files
authored
Linearization (#4)
* Add led brightness linearization
1 parent 715f574 commit dbe63db

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

app/main.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import json
88
import signal
99
import threading
10+
import math
1011
from datetime import datetime
1112
import modbus_tk
1213
import modbus_tk.defines as cst
@@ -31,6 +32,12 @@ def getenv():
3132
'ec133': {
3233
'addr': os.environ.get('EC133_ADDR', 1),
3334
'timeout': os.environ.get('EC133_TIMEOUT', 0.2),
35+
'linearization': {
36+
'active': bool(os.environ.get('LINEARIZE', True)),
37+
'range': float(os.environ.get('LINEARIZE_RANGE', 255)),
38+
'offset': float(os.environ.get('LINEARIZE_OFFSET', 0.05)),
39+
'tau': float(os.environ.get('LINEARIZE_TAU', 0.55))
40+
},
3441
'command_topics': {
3542
'0': os.environ.get('CH0_COMMAND', ''),
3643
'1': os.environ.get('CH1_COMMAND', ''),
@@ -103,6 +110,29 @@ def connect(self):
103110
msg("Unable to initialize RTU master")
104111
raise e
105112

113+
def _linearize(self,ch):
114+
115+
linconf = self.ecconf.get('linearization')
116+
117+
if linconf.get('active', False) == False:
118+
return
119+
120+
ch = int(ch)
121+
new = self.register
122+
123+
if self.register[ch] < 10:
124+
return
125+
126+
# f(x) = range*(1-offset)*exp(-(1-(x/range))/tau) + range*offset
127+
exponent = (-1 * ( 1 - ( float(new[ch]) / linconf['range']))) / linconf['tau']
128+
new[ch] = int(linconf['range']
129+
* (1 - linconf['offset'])
130+
* math.exp(exponent)
131+
+ (linconf['range'] * linconf['offset'])
132+
)
133+
msg("Linearized as : %s" % str(new))
134+
self.register = new
135+
106136
def set_channel(self, client, userdata, message):
107137

108138
ch = int(userdata['channel'])
@@ -125,13 +155,14 @@ def set_channel(self, client, userdata, message):
125155
self.brightness[ch] = int(payload['brightness'])
126156
else:
127157
payload['brightness'] = int(self.brightness[ch])
128-
print(payload)
129158

130159
if payload.get('state', 'ON') == 'ON':
131160
self.register[ch] = int(self.brightness[ch])
132161
else:
133162
self.register[ch] = int(0)
134163

164+
self._linearize(ch)
165+
135166
try:
136167
self.rtu.execute(self.ecconf['addr'],
137168
cst.WRITE_MULTIPLE_REGISTERS,

linearization/README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Linearization
2+
3+
## Why do we need an linearization
4+
5+
EC133 is a PWM chopper. Brightness of leds is somewhat proportional to the logarythm of Voltage.
6+
Without linearization it would be more difficult to obtain desired brightness.
7+
8+
You can use gnuplot to help yours self with parameters:
9+
10+
```
11+
set term x11 enhanced font "terminal-14"
12+
set xrange [0:255]
13+
set yrange [0:255]
14+
range=255
15+
tau=0.5;
16+
offset=0.05
17+
f(x) = range*(1-offset)*exp(-(1-(x/range))/(0.3)) + range*offset
18+
plot f(x) with lines
19+
tau=0.1
20+
f(x) = range*(1-offset)*exp(-(1-(x/range))/tau) + range*offset ; replot
21+
```

0 commit comments

Comments
 (0)