Commit d9670374 authored by Guillaume Blanchy's avatar Guillaume Blanchy
Browse files

adding materials for dashboard

Showing with 18274 additions and 67 deletions
+18274 -67
.gitignore 0 → 100644
data/*.csv
**/.ipynb_notebooks/**
data.zip
...@@ -15,41 +15,50 @@ print('OhmPi start' ) ...@@ -15,41 +15,50 @@ print('OhmPi start' )
print('Vers: 1.51') print('Vers: 1.51')
print('Import library') print('Import library')
import os
import sys
import json
import glob
import numpy as np
import pandas as pd
import time
from datetime import datetime
from termcolor import colored
"""
import time , board, busio, numpy, os, sys, json, glob,os.path,adafruit_tca9548a import board, busio,adafruit_tca9548a
import adafruit_ads1x15.ads1115 as ADS import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn from adafruit_ads1x15.analog_in import AnalogIn
from pandas import DataFrame
from datetime import datetime
from adafruit_mcp230xx.mcp23008 import MCP23008 from adafruit_mcp230xx.mcp23008 import MCP23008
from adafruit_mcp230xx.mcp23017 import MCP23017 from adafruit_mcp230xx.mcp23017 import MCP23017
import digitalio import digitalio
from digitalio import Direction from digitalio import Direction
from gpiozero import CPUTemperature from gpiozero import CPUTemperature
"""
current_time = datetime.now() current_time = datetime.now()
print(current_time.strftime("%Y-%m-%d %H:%M:%S")) print(current_time.strftime("%Y-%m-%d %H:%M:%S"))
""" """
Hardware parameters Hardware parameters
""" """
R_shunt = 0.2# reference resistance value in ohm R_shunt = 0.2# reference resistance value in ohm
Imax=4800/50/2 Imax = 4800/50/2
print(colored('The maximum current cannot be higher than 48 mA', 'red')) print(colored('The maximum current cannot be higher than 48 mA', 'red'))
coef_p2 = 2.50# slope for current conversion for ADS.P2, measurement in V/V coef_p2 = 2.50# slope for current conversion for ADS.P2, measurement in V/V
coef_p3 = 2.50 # slope for current conversion for ADS.P3, measurement in V/V coef_p3 = 2.50 # slope for current conversion for ADS.P3, measurement in V/V
offset_p2= 0 offset_p2= 0
offset_p3= 0 offset_p3= 0
integer=10 integer=10
meas=numpy.zeros((3,integer)) meas=np.zeros((3,integer))
""" """
Import parameters Import parameters
""" """
with open('ohmpi_param.json') as json_file: #with open('ohmpi_param.json') as json_file:
pardict = json.load(json_file) # pardict = json.load(json_file)
"""
i2c = busio.I2C(board.SCL, board.SDA) #activation du protocle I2C i2c = busio.I2C(board.SCL, board.SDA) #activation du protocle I2C
mcp = MCP23008(i2c, address=0x20) #connexion I2C MCP23008, injection de courant mcp = MCP23008(i2c, address=0x20) #connexion I2C MCP23008, injection de courant
ads_current = ADS.ADS1115(i2c, gain=16,data_rate=860, address=0X48)# connexion ADS1115, pour la mesure de courant ads_current = ADS.ADS1115(i2c, gain=16,data_rate=860, address=0X48)# connexion ADS1115, pour la mesure de courant
...@@ -68,12 +77,13 @@ Elec_A= adafruit_tca9548a.TCA9548A(i2c, 0X76) ...@@ -68,12 +77,13 @@ Elec_A= adafruit_tca9548a.TCA9548A(i2c, 0X76)
Elec_B= adafruit_tca9548a.TCA9548A(i2c, 0X71) Elec_B= adafruit_tca9548a.TCA9548A(i2c, 0X71)
Elec_M= adafruit_tca9548a.TCA9548A(i2c, 0X74) Elec_M= adafruit_tca9548a.TCA9548A(i2c, 0X74)
Elec_N= adafruit_tca9548a.TCA9548A(i2c, 0X70) Elec_N= adafruit_tca9548a.TCA9548A(i2c, 0X70)
"""
""" """
functions functions
""" """
"""
# function swtich_mux select the right channels for the multiplexer cascade for electrodes A, B, M and N. # function swtich_mux select the right channels for the multiplexer cascade for electrodes A, B, M and N.
def switch_mux_on(quadripole): def switch_mux_on(quadripole):
elec_adress=[0x76,0X71,0x74,0x70] elec_adress=[0x76,0X71,0x74,0x70]
...@@ -146,42 +156,6 @@ def ZERO_mux(nb_elec): ...@@ -146,42 +156,6 @@ def ZERO_mux(nb_elec):
mcp2.get_pin(a-1).direction=digitalio.Direction.OUTPUT mcp2.get_pin(a-1).direction=digitalio.Direction.OUTPUT
mcp2.get_pin(a-1).value= False mcp2.get_pin(a-1).value= False
# function to find rows with identical values in different columns
def find_identical_in_line(array_object):
output = []
if array_object.ndim == 1:
temp = numpy.zeros(4)
for i in range(len(array_object)):
temp[i] = numpy.count_nonzero(array_object == array_object[i])
if any(temp > 1):
output.append(0)
else:
for i in range(len(array_object[:,1])):
temp = numpy.zeros(len(array_object[1,:]))
for j in range(len(array_object[1,:])):
temp[j] = numpy.count_nonzero(array_object[i,:] == array_object[i,j])
if any(temp > 1):
output.append(i)
return output
#
# read quadripole file and apply tests
def read_quad(filename, nb_elec):
output = numpy.loadtxt(filename, delimiter=" ",dtype=int) # load quadripole file
# locate lines where the electrode index exceeds the maximum number of electrodes
test_index_elec = numpy.array(numpy.where(output > nb_elec))
# locate lines where an electrode is referred twice
test_same_elec = find_identical_in_line(output)
# if statement with exit cases (rajouter un else if pour le deuxième cas du ticket #2)
if test_index_elec.size != 0:
for i in range(len(test_index_elec[0,:])):
print("Error: An electrode index at line "+ str(test_index_elec[0,i]+1)+" exceeds the maximum number of electrodes")
sys.exit(1)
elif len(test_same_elec) != 0:
for i in range(len(test_same_elec)):
print("Error: An electrode index is used twice at line " + str(test_same_elec[i]+1))
sys.exit(1)
else:
return output
def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_array): def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_array):
start_time=time.time() start_time=time.time()
...@@ -217,8 +191,8 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar ...@@ -217,8 +191,8 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar
meas[2,k] = AnalogIn(ads_voltage,ADS.P1).voltage * coefp3*1000 # reading voltage value on ADS channel A2 meas[2,k] = AnalogIn(ads_voltage,ADS.P1).voltage * coefp3*1000 # reading voltage value on ADS channel A2
pin1.value = False; pin0.value = False# stop current injection pin1.value = False; pin0.value = False# stop current injection
end_delay=time.time() end_delay=time.time()
sum_I=sum_I+(numpy.mean(meas[0,:])) sum_I=sum_I+(np.mean(meas[0,:]))
Vmn1=((numpy.mean(meas[1,:]))-(numpy.mean(meas[2,:]))) Vmn1=((np.mean(meas[1,:]))-(np.mean(meas[2,:])))
if (n % 2) == 0: if (n % 2) == 0:
sum_Vmn=sum_Vmn-Vmn1 sum_Vmn=sum_Vmn-Vmn1
sum_Ps=sum_Ps+Vmn1 sum_Ps=sum_Ps+Vmn1
...@@ -230,7 +204,7 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar ...@@ -230,7 +204,7 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar
time.sleep((end_delay-start_delay)-(end_calc-end_delay)) time.sleep((end_delay-start_delay)-(end_calc-end_delay))
# return averaged values # return averaged values
# cpu= CPUTemperature() # cpu= CPUTemperature()
output = DataFrame({ output = pd.DataFrame({
"time":[datetime.now()], "time":[datetime.now()],
"A":elec_array[0], "A":elec_array[0],
"B":elec_array[1], "B":elec_array[1],
...@@ -258,6 +232,45 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar ...@@ -258,6 +232,45 @@ def run_measurement(nb_stack, injection_deltat, R_shunt, coefp2, coefp3, elec_ar
time.sleep(1) time.sleep(1)
return output return output
"""
# function to find rows with identical values in different columns
def find_identical_in_line(array_object):
output = []
if array_object.ndim == 1:
temp = np.zeros(4)
for i in range(len(array_object)):
temp[i] = np.count_nonzero(array_object == array_object[i])
if any(temp > 1):
output.append(0)
else:
for i in range(len(array_object[:,1])):
temp = np.zeros(len(array_object[1,:]))
for j in range(len(array_object[1,:])):
temp[j] = np.count_nonzero(array_object[i,:] == array_object[i,j])
if any(temp > 1):
output.append(i)
return output
# read quadripole file and apply tests
def read_quad(filename, nb_elec):
output = np.loadtxt(filename, delimiter=" ",dtype=int) # load quadripole file
# locate lines where the electrode index exceeds the maximum number of electrodes
test_index_elec = np.array(np.where(output > nb_elec))
# locate lines where an electrode is referred twice
test_same_elec = find_identical_in_line(output)
# if statement with exit cases (rajouter un else if pour le deuxième cas du ticket #2)
if test_index_elec.size != 0:
for i in range(len(test_index_elec[0,:])):
print("Error: An electrode index at line "+ str(test_index_elec[0,i]+1)+" exceeds the maximum number of electrodes")
sys.exit(1)
elif len(test_same_elec) != 0:
for i in range(len(test_same_elec)):
print("Error: An electrode index is used twice at line " + str(test_same_elec[i]+1))
sys.exit(1)
else:
return output
# save data # save data
def append_and_save(path, last_measurement): def append_and_save(path, last_measurement):
...@@ -274,24 +287,68 @@ def append_and_save(path, last_measurement): ...@@ -274,24 +287,68 @@ def append_and_save(path, last_measurement):
""" """
Main loop Main loop
""" """
N=read_quad("dd.txt",pardict.get("nb_electrodes")) # load quadripole file import threading
if N.ndim == 1: class OhmPi(object):
N = N.reshape(1, 4) def __init__(self, pardict):
ZERO_mux(pardict.get("nb_electrodes")) self.status = 'idle'
for g in range(0,pardict.get("nbr_meas")): # for time-lapse monitoring self.run = True
self.t = None
self.pardict = pardict
for i in range(0,N.shape[0]): # loop over quadripoles def measure(self):
# call the switch_mux function to switch to the right electrodes self.run = True
self.status = 'running'
N = read_quad("dd.txt", self.pardict.get("nb_electrodes")) # load quadripole file
switch_mux_on(N[i,])
# run a measurement if N.ndim == 1:
current_measurement = run_measurement(pardict.get("stack"), pardict.get("injection_duration"), R_shunt, coef_p2, coef_p3, N[i,]) N = N.reshape(1, 4)
switch_mux_off(N[i,])
#save data and print in a text file def func():
append_and_save(pardict.get("export_path"), current_measurement) for g in range(0, self.pardict.get("nbr_meas")): # for time-lapse monitoring
print(i+1,'/',N.shape[0]) if self.run == False:
print('end of sequence') print('INTERRUPTED')
ZERO_mux(pardict.get("nb_electrodes")) break
time.sleep(pardict.get("sequence_delay")) #waiting next measurement (time-lapse) t0 = time.time()
fname = self.pardict.get("export_path").replace('.csv', '_' + datetime.now().strftime('%Y%m%dT%H%M%S') + '.csv')
print('saving to ', fname)
print('\r{:d}/{:d}'.format(0, N.shape[0]), end='')
#ZERO_mux(self.pardict.get("nb_electrodes"))
for i in range(0,N.shape[0]): # loop over quadripoles
if self.run == False:
break
# call the switch_mux function to switch to the right electrodes
#switch_mux_on(N[i,])
# run a measurement
#current_measurement = run_measurement(self.pardict.get("stack"), pardict.get("injection_duration"), R_shunt, coef_p2, coef_p3, N[i,])
#switch_mux_off(N[i,])
current_measurement = pd.DataFrame({
'a': [N[i, 0]], 'b': [N[i, 1]], 'm': [N[i, 2]], 'n': [N[i, 3]], 'rho': np.abs(np.random.randn(1))
})
time.sleep(np.abs(np.random.randn(1))[0])
# save data and print in a text file
append_and_save(fname, current_measurement)
print('\r{:d}/{:d}'.format(i+1, N.shape[0]), end='')
print('end of sequence')
measuring_time = time.time() - t0
sleep_time = self.pardict.get("sequence_delay") - measuring_time
if sleep_time < 0:
# it means that the measuring time took longer than the sequence delay
sleep_time = 0
# sleeping time between sequence (not good now)
if self.pardict.get("nbr_meas") > 1:
time.sleep(sleep_time) #waiting next measurement (time-lapse)
self.status = 'idle'
self.t = threading.Thread(target=func)
self.t.start()
def stop(self):
self.run = False
if self.t is not None:
self.t.join()
print('self.status', self.status)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
@-ms-viewport {
width: device-width;
}
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */
\ No newline at end of file
This diff is collapsed.
/*!
* Bootstrap Reboot v4.0.0 (https://getbootstrap.com)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
In this folder will be logged all measurements done with the OhmPi as .csv.
index.html 0 → 100644
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment