summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-05-22 16:49:27 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-05-22 16:49:49 +0200
commitdc5a3c90ff5efc63959f7bfd5d68e5dcda1ad477 (patch)
treec386360b7705272da865304efe66c3ba585db639
parent6b1a22278f7e8a649c8162de98e352e3f10943ad (diff)
cycles/radio to energy: Add esp8266
-rw-r--r--lib/cycles_to_energy.py39
-rw-r--r--lib/size_to_radio_energy.py63
2 files changed, 98 insertions, 4 deletions
diff --git a/lib/cycles_to_energy.py b/lib/cycles_to_energy.py
index 18b0629..35f9199 100644
--- a/lib/cycles_to_energy.py
+++ b/lib/cycles_to_energy.py
@@ -15,6 +15,8 @@ def get_class(cpu_name):
return ATMega328
if cpu_name == 'ATTiny88':
return ATTiny88
+ if cpu_name == 'esp8266':
+ return ESP8266
def _param_list_to_dict(device, param_list):
param_dict = dict()
@@ -60,7 +62,7 @@ class MSP430:
def get_energy_per_cycle(params):
if type(params) != dict:
- return MSP430.get_energy(_param_list_to_dict(MSP430, params))
+ return MSP430.get_energy_per_cycle(_param_list_to_dict(MSP430, params))
return MSP430.get_power(params) / params['cpu_freq']
@@ -94,7 +96,7 @@ class ATMega168:
def get_energy_per_cycle(params):
if type(params) != dict:
- return ATMega168.get_energy(_param_list_to_dict(ATMega168, params))
+ return ATMega168.get_energy_per_cycle(_param_list_to_dict(ATMega168, params))
return ATMega168.get_power(params) / params['cpu_freq']
@@ -132,10 +134,41 @@ class ATMega328:
def get_energy_per_cycle(params):
if type(params) != dict:
- return ATMega328.get_energy(_param_list_to_dict(ATMega328, params))
+ return ATMega328.get_energy_per_cycle(_param_list_to_dict(ATMega328, params))
return ATMega328.get_power(params) / params['cpu_freq']
+class ESP8266:
+ # Source: ESP8266EX Datasheet, table 5-2 (v2017.11) / table 3-4 (v2018.11)
+ # Taken at 3.0V
+ name = 'ESP8266'
+ parameters = {
+ 'cpu_freq': [80e6],
+ 'voltage': [2.5, 3.0, 3.3, 3.6] # min / ... / typ / max
+ }
+ default_params = {
+ 'cpu_freq': 80e6,
+ 'voltage': 3.0
+ }
+
+ def get_current(params):
+ if type(params) != dict:
+ return ESP8266.get_current(_param_list_to_dict(ESP8266, params))
+
+ return 15e-3
+
+ def get_power(params):
+ if type(params) != dict:
+ return ESP8266.get_power(_param_list_to_dict(ESP8266, params))
+
+ return ESP8266.get_current(params) * params['voltage']
+
+ def get_energy_per_cycle(params):
+ if type(params) != dict:
+ return ESP8266.get_energy_per_cycle(_param_list_to_dict(ESP8266, params))
+
+ return ESP8266.get_power(params) / params['cpu_freq']
+
class ATTiny88:
name = 'ATTiny88'
parameters = {
diff --git a/lib/size_to_radio_energy.py b/lib/size_to_radio_energy.py
index 808ff9b..83b2116 100644
--- a/lib/size_to_radio_energy.py
+++ b/lib/size_to_radio_energy.py
@@ -15,6 +15,8 @@ def get_class(radio_name: str):
return NRF24L01tx
if radio_name == 'NRF24L01dtx':
return NRF24L01dtx
+ if radio_name == 'esp8266dtx':
+ return ESP8266dtx
def _param_list_to_dict(device, param_list):
param_dict = dict()
@@ -40,6 +42,7 @@ class CC1200tx:
return CC1200tx.get_energy(_param_list_to_dict(CC1200tx, params))
# Mittlere TX-Leistung, gefitted von AEMR
+ # Messdaten erhoben bei 3.6V
power = 8.18053941e+04
power -= 1.24208376e+03 * np.sqrt(params['symbolrate'])
power -= 5.73742779e+02 * np.log(params['txbytes'])
@@ -57,6 +60,7 @@ class CC1200tx:
# TX-Energie, gefitted von AEMR
# Achtung: Energy ist in µJ, nicht (wie in AEMR-Transitionsmodellen üblich) in pJ
+ # Messdaten erhoben bei 3.6V
energy = 1.74383259e+01
energy += 6.29922138e+03 * 1/(params['symbolrate'])
@@ -98,8 +102,9 @@ class CC1200tx:
return de_dx * 1e-6
+# PYTHONPATH=lib bin/analyze-archive.py --show-model=all --show-quality=table ../data/*_RF24_no_retries.tar
class NRF24L01tx:
- """NRF24L01+ TX energy based on aemr measurements (32B fixed packet size, ack-await, no retries)."""
+ """NRF24L01+ TX(*) energy based on aemr measurements (32B fixed packet size, (*)ack-await, no retries)."""
name = 'NRF24L01'
parameters = {
'datarate' : [250, 1000, 2000], # kbps
@@ -113,22 +118,51 @@ class NRF24L01tx:
'voltage' : 3,
}
+# AEMR:
+# TX power / energy:
+#TX : 0 + regression_arg(0) + regression_arg(1) * 1/(parameter(datarate)) + regression_arg(2) * (19.47+parameter(txpower))**2 + regression_arg(3) * 1/(parameter(datarate)) * (19.47+parameter(txpower))**2
+# [6.30323056e+03 2.59889924e+06 7.82186268e+00 8.69746093e+03]
+#TX : 0 + regression_arg(0) + regression_arg(1) * 1/(parameter(datarate)) + regression_arg(2) * (19.47+parameter(txpower))**2 + regression_arg(3) * 1/(parameter(datarate)) * (19.47+parameter(txpower))**2
+# [7.67932887e+00 1.02969455e+04 4.55116475e-03 2.99786534e+01]
+#epilogue : timeout : 0 + regression_arg(0) + regression_arg(1) * 1/(parameter(datarate))
+# [ 1624.06589147 332251.93798766]
+
+
+
def get_energy(params):
if type(params) != dict:
return NRF24L01tx.get_energy(_param_list_to_dict(NRF24L01tx, params))
+ # TX-Leistung, gefitted von AEMR
+ # Messdaten erhoben bei 3.6V
power = 6.30323056e+03
power += 2.59889924e+06 * 1/params['datarate']
power += 7.82186268e+00 * (19.47+params['txpower'])**2
power += 8.69746093e+03 * 1/params['datarate'] * (19.47+params['txpower'])**2
+ # TX-Dauer, gefitted von AEMR
duration = 1624.06589147
duration += 332251.93798766 * 1/params['datarate']
+ # TX-Energie, gefitted von AEMR
+ # Achtung: Energy ist in µJ, nicht (wie in AEMR-Transitionsmodellen üblich) in pJ
+ # Messdaten erhoben bei 3.6V
+ energy = 7.67932887e+00
+ energy += 1.02969455e+04 * 1/params['datarate']
+ energy += 4.55116475e-03 * (19.47+params['txpower'])**2
+ energy += 2.99786534e+01 * 1/params['datarate'] * (19.47+params['txpower'])**2
+
energy = power * 1e-6 * duration * 1e-6 * np.ceil(params['txbytes'] / 32)
return energy
+ def get_energy_per_byte(params):
+ if type(params) != dict:
+ return NRF24L01tx.get_energy_per_byte(_param_list_to_dict(NRF24L01tx, params))
+
+ # in µJ
+ de_dx = 0
+
class NRF24L01dtx:
"""nRF24L01+ TX energy based on datasheet values (probably unerestimated)"""
@@ -169,3 +203,30 @@ class NRF24L01dtx:
energy += current * params['voltage'] * ((header_bytes + params['txbytes']) * 8 / (params['datarate'] * 1e3))
return energy
+
+class ESP8266dtx:
+ """esp8266 TX energy based on (hardly documented) datasheet values)"""
+ name = 'esp8266'
+ parameters = {
+ 'voltage' : [2.5, 3.0, 3.3, 3.6],
+ 'txbytes' : [],
+ 'bitrate' : [65e6],
+ 'tx_current' : [120e-3],
+ }
+ default_params = {
+ 'voltage' : 3,
+ 'bitrate' : 65e6,
+ 'tx_current' : 120e-3
+ }
+
+ def get_energy(params):
+ # TODO
+ return 0
+
+ def get_energy_per_byte(params):
+ if type(params) != dict:
+ return ESP8266dtx.get_energy_per_byte(_param_list_to_dict(ESP8266dtx, params))
+
+ # TX in 802.11n MCS7 -> 64QAM, 65/72.2 Mbit/s @ 20MHz channel, 135/150 Mbit/s @ 40MHz
+ # -> Value for 65 Mbit/s @ 20MHz channel
+ return params['tx_current'] * params['voltage'] / params['bitrate']