Skip to content

Commit

Permalink
Linearization (#4)
Browse files Browse the repository at this point in the history
* Add led brightness linearization
  • Loading branch information
bojleros authored Oct 25, 2018
1 parent 715f574 commit dbe63db
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
33 changes: 32 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import json
import signal
import threading
import math
from datetime import datetime
import modbus_tk
import modbus_tk.defines as cst
Expand All @@ -31,6 +32,12 @@ def getenv():
'ec133': {
'addr': os.environ.get('EC133_ADDR', 1),
'timeout': os.environ.get('EC133_TIMEOUT', 0.2),
'linearization': {
'active': bool(os.environ.get('LINEARIZE', True)),
'range': float(os.environ.get('LINEARIZE_RANGE', 255)),
'offset': float(os.environ.get('LINEARIZE_OFFSET', 0.05)),
'tau': float(os.environ.get('LINEARIZE_TAU', 0.55))
},
'command_topics': {
'0': os.environ.get('CH0_COMMAND', ''),
'1': os.environ.get('CH1_COMMAND', ''),
Expand Down Expand Up @@ -103,6 +110,29 @@ def connect(self):
msg("Unable to initialize RTU master")
raise e

def _linearize(self,ch):

linconf = self.ecconf.get('linearization')

if linconf.get('active', False) == False:
return

ch = int(ch)
new = self.register

if self.register[ch] < 10:
return

# f(x) = range*(1-offset)*exp(-(1-(x/range))/tau) + range*offset
exponent = (-1 * ( 1 - ( float(new[ch]) / linconf['range']))) / linconf['tau']
new[ch] = int(linconf['range']
* (1 - linconf['offset'])
* math.exp(exponent)
+ (linconf['range'] * linconf['offset'])
)
msg("Linearized as : %s" % str(new))
self.register = new

def set_channel(self, client, userdata, message):

ch = int(userdata['channel'])
Expand All @@ -125,13 +155,14 @@ def set_channel(self, client, userdata, message):
self.brightness[ch] = int(payload['brightness'])
else:
payload['brightness'] = int(self.brightness[ch])
print(payload)

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

self._linearize(ch)

try:
self.rtu.execute(self.ecconf['addr'],
cst.WRITE_MULTIPLE_REGISTERS,
Expand Down
21 changes: 21 additions & 0 deletions linearization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Linearization

## Why do we need an linearization

EC133 is a PWM chopper. Brightness of leds is somewhat proportional to the logarythm of Voltage.
Without linearization it would be more difficult to obtain desired brightness.

You can use gnuplot to help yours self with parameters:

```
set term x11 enhanced font "terminal-14"
set xrange [0:255]
set yrange [0:255]
range=255
tau=0.5;
offset=0.05
f(x) = range*(1-offset)*exp(-(1-(x/range))/(0.3)) + range*offset
plot f(x) with lines
tau=0.1
f(x) = range*(1-offset)*exp(-(1-(x/range))/tau) + range*offset ; replot
```

0 comments on commit dbe63db

Please sign in to comment.