実現したいこと
Pythonにてプログラムを作成しました。
が、古いC言語の知識しか無いので、プログラムがあまり簡素に出来ません。
以下のプログラムを簡素化する場合は、クラスを使えば簡素に出来るのか?
または、別の手法があるのか?
アドバイスを頂けると幸いです。
オブジェクト指向を勉強していますが、実際に適用するとなると難しくなやんでいます。
前提
ラズベリーパイにて、Pythonにてプログラムを製作しました。
7つのデバイスの測定値を受け取ります。
関数を作成し、引数にてデバイスを指定し
・デバイスの初期化
・測定値の入手
・測定値の表示
・測定値のファイル書き込み
をそれぞれ各関数にて行っています。
したがって、7台を制御するプログラムは、4つの関数を7台分記述しています。
これを簡素に出来ないか?と考えています。
該当のソースコード
Python
1#抜粋 例えば2台のデバイスを制御する場合 2#見やすくするために、関数定義は後半に記載 3 4#初期化 5init_ina226(INA226_ADDR_1,CONFIG_VALUE_1,SHANT_OHM_VALUE_1) 6init_ina226(INA226_ADDR_3,CONFIG_VALUE_1,SHANT_OHM_VALUE_1) 7 8#測定メインループ 9#1台目 10meas_results_1= get_result(INA226_ADDR_1,SHUNT_OHM_1) 11print_result(1,meas_results_1[0],meas_results_1[1],meas_results_1[2],meas_results_1[3],meas_results_1[4],meas_results_1[5]) 12savedata(1,meas_results_1[5],meas_results_1[3]) 13 14#2台目 15meas_results_2= get_result(INA226_ADDR_1,SHUNT_OHM_1) 16print_result(2,meas_results_2[0],meas_results_2[1],meas_results_2[2],meas_results_2[3],meas_results_2[4],meas_results_2[5]) 17savedata(2,meas_results_2[5],meas_results_2[3]) 18 19#関数定義 20def get_result(dev_addr,shant_ohm): 21 busvolt = conv_busbolt(read_ina226(dev_addr,BUS_V_REG_ADDR)) 22 shuntvolt = conv_shuntbolt(read_ina226(dev_addr,SHUNT_V_RED_ADDR)) 23 current = conv_curr(read_ina226(dev_addr,CURR_REG_ADDR)) 24 #power = conv_pow(read_ina226(INA226_ADDR_1,POW_REG_ADDR)) 25 power = f'{conv_pow(read_ina226(dev_addr,POW_REG_ADDR)):.3f}' 26 27 calc_i=calc_curr(shuntvolt,shant_ohm) 28 calc_power=f'{calc_pow(busvolt,calc_i):.3f}' 29 30 return busvolt,shuntvolt,current,power,calc_i,calc_power 31
考えていること
Ptyhonの勉強をしていると(+JaxaScriptも)
・関数の引数を「関数で渡せる」
・配列の最後に値を入れるpushメソッドがある
こと自体に驚いています。
現在の私の考えですと、接続台数でifを書いて、meas_result_xを、二次元配列にして・・・
とどうしても手続き型で考えてしまいます。
オブジェクト指向でのスッキリしたプログラムの考え方をアドバイス頂けると幸いです。
2023/8/23追記
現状のクラス化のプログラム
# -*- coding: utf-8 -*- ''' 2023/7/1 TI製のIC「INA226」を使ったストロベリーリナックス製の 「INA226iso」を使った基本プログラム 2023/07/06 複数台に対応できるように汎用化している。 ファイルライトも各ファイルにて書き出し可能 I2C用のライブラリはsmbus2が主流らしいが、デフォルトではまだ入っていないので smbusを使う。 後学の為に、冗長表現がある。 1.数値の桁数の操作 a.PrintResult()内で、print時にfloatの数字の小数点を3桁にしている b.calcPower=f'{calc_pow(busvolt,calc_i):.4f}' で、printを使用しない場合での桁数を指定している これは後からファイルライトしている。 ''' import smbus import time import datetime import File_w_time as FW i2c = smbus.SMBus(1) #I2Cチャンネルの指定(基本は「1」) ''' ユーザーで変更するのは以下の4つだが、基本的には2つしか変更しない 1. INA226_ADDR_1 :デバイスの物理的なアドレス。ハンダでA1とA0をショートさせて16パターンから選ぶ 2. CONFIG_VALUE :AD変換の平均回数や返還時間のパラメータ変更 ***複数台接続時のほとんどの場合は、デバイスアドレスのみを変更すればOK ∵AD変換の回数等は同じ場合が多い 以下の2つはストロベリーリナックスのモジュールについているシャント抵抗なので基本的には変更しない 3. SHANT_OHM_VALUE -> : IC内部演算で電流値や電力を計算するときに使う 4. SHUNT_OHM -> 手計算用 : get_result()内のcalc_curr()にて使用 ''' DIR_PATH = './log' INTERVAL_MEAS = 1 #電力測定の間隔[s]。台数分の積が1サイクルとなる。例)2[s] x 7台 = 14[s] / 1サイクル '''以下は変更しない定数''' CONFIG_REG_ADDR = 0x00 SHUNT_V_RED_ADDR = 0x01 BUS_V_REG_ADDR = 0x02 POW_REG_ADDR = 0x03 CURR_REG_ADDR = 0x04 CAL_SHANTOHM_REG_ADDR = 0x05 class Ina226(): def __init__(self,dev_addr,conf,shant_ohm_hex,shant_ohm): self.dev_addr = dev_addr self.conf = conf self.shant_ohm_hex = shant_ohm_hex self.shant_ohm = shant_ohm def read_ina226(self,dev_addr,reg_addr): word = i2c.read_word_data(dev_addr, reg_addr) & 0xFFFF digitresult = ( (word << 8) & 0xFF00 ) + (word >> 8) return digitresult time.sleep(0.05) def write_ina226(self,dev_addr,reg_addr,code ): i2c.write_i2c_block_data(dev_addr,reg_addr,code) time.sleep(0.1) def init_ina226(self): self.write_ina226(self.dev_addr,CONFIG_REG_ADDR,self.conf) self.write_ina226(self.dev_addr,CAL_SHANTOHM_REG_ADDR,self.shant_ohm_hex) def get_result(self): busvolt = self.conv_busbolt(self.read_ina226(self.dev_addr,BUS_V_REG_ADDR)) shuntvolt = self.conv_shuntbolt(self.read_ina226(self.dev_addr,SHUNT_V_RED_ADDR)) current = self.conv_curr(self.read_ina226(self.dev_addr,CURR_REG_ADDR)) power = f'{self.conv_pow(self.read_ina226(self.dev_addr,POW_REG_ADDR)):.3f}' calc_i=self.calc_curr(shuntvolt,self.shant_ohm) calc_power=f'{self.calc_pow(busvolt,calc_i):.3f}' return [busvolt,shuntvolt,current,power,calc_i,calc_power] def print_result(self,num,busvolt,shuntvolt,current,power,calc_i,calc_power): print('----------%d台目の測定結果--------------'%num) print(f'busvolt = {busvolt:.4f}[V] , shuntvolt ={shuntvolt:.4f}') print(f'calc I = {calc_i:.3f}[A] , Meas I = {current:.3f}[A]') print(f'calc W = {float(calc_power):.3f}[W] , Meas W = {float(power):.3f}[W]') print('---------------------------------------') def savedata(self,dir_path,prefix,calc_power,power): texttime = datetime.datetime.now().strftime('%H:%M:%S') addpath = FW.make_tspath(dir_path,prefix) adddata = texttime +'\t'+ str(calc_power)+ '\t'+ str(power)+ '\n' FW.faddtxt(addpath,adddata) ### get_result用の関数 ### def conv_busbolt(self,digitval): busvolt = digitval * 1.25 /1000 # digit unit is [mV] so, divided by 1000 return busvolt def conv_shuntbolt(self,digitval): shuntvolt = digitval * 2.5 /(1000 *1000) # digit unit is [uV] so, divided by 1000*1000 return shuntvolt def conv_curr(self,digitval): current = digitval *1.0 / 1000 # digit unit is [mA] return current def conv_pow(self,digitval): power = digitval *25.0 / 1000 # digit unit is [mW] return power def calc_curr(self,shuntbolt,shuntorm): #input unit is [v][Ohm] not [mV] and [mOhm] calc_curr = shuntbolt / shuntorm return calc_curr def calc_pow(self,busvolt,current): power = busvolt * current return power if __name__ == '__main__': conf_list = [{'dev_addr':0x40, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x41, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x42, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x43, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x44, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x45, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002}, {'dev_addr':0x46, 'conf':[0x41,0x27], 'shant_ohm_hex':[0x0A,0x00], 'shant_ohm':0.002} ] ina226_list =[] for dev in conf_list: new_ina = Ina226(dev['dev_addr'],dev['conf'],dev['shant_ohm_hex'],dev['shant_ohm']) ina226_list.append(new_ina) for dev in range(len(ina226_list)): ina226_list[dev].init_ina226() #print( ina226_list[1].dev_addr) print(len(ina226_list)) while(True): for dev in range(len(ina226_list)): res = ina226_list[dev].get_result() ina226_list[dev].print_result(dev,*res) ina226_list[dev].savedata(DIR_PATH,dev,res[5],res[3]) time.sleep(INTERVAL_MEAS)

回答1件
あなたの回答
tips
プレビュー