続いて、SWの最終形はこんなかんじ。
CT2DB.py(ラズパイ側常時起動プログラム)
import time
import datetime
import MySQLdb
from datetime import datetime as dt
import smtplib
import ssl
from email import encoders
from email import message
from email.mime import multipart
from email.mime import text
import serial
#ttyACM0はタイミングによって変わる可能性あり
ser = serial.Serial('/dev/ttyACM0', 115200)
filename = "ログファイル"
#メールを大量に送信しないようにするためのフラグ
sendmail = 0
from subprocess import getoutput
def _update():
# ADCの電圧を取得する(USBより)
str_serial = ""
str_serial = ser.readline()
while ser.in_waiting:
str_serial = str_serial + ser.readline()
#ラズピコからのテキストデータを整形する
str_serial = str(str_serial).replace('b', '').replace('\\r\\n', '').replace('\'', '')
nowdatastr = str(str_serial)
str_list = str(str_serial).split(',')
#データべースへの書き込み
connector = MySQLdb.connect(host="localhost", db="log_current", user="root", passwd="パスワード", charset="utf8")
cursor = connector.cursor()
sql = u"insert into current values(now(), %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (str_list[0] , str_list[1] , str_list[2] , str_list[3] , str_list[4] , str_list[5] , str_list[6] , str_list[7] , str_list[8]> #print(sql)
try:
cursor.execute(sql)
except MySQLdb.Error as e:
print(e)
nowtime = dt.now()
nowtimestr = nowtime.strftime('%Y/%m/%d %H:%M:%S')
fileobj = open(file, 'a', encoding='UTF-8')
fileobj.write(nowtimestr)
fileobj.write(e)
fileobj.close()
connector.commit()
cursor.close()
#画面表示用の整形 0.4A以下の場合はノイズと区別がつかないので( )をつける
for i in range(10):
if float(str_list[i]) < 0.4:
str_list[i] = "(" + str_list[i][:5] + "A)"
else:
str_list[i] = str_list[i][:5] + "A"
str_list[16] = str_list[16][:4]
#標準出力へ表示
nowtime = dt.now()
nowtimestr = nowtime.strftime('%Y/%m/%d %H:%M:%S')
print(nowtimestr);
print("CH0:" + str_list[0])
print("CH1:" + str_list[1])
print("CH2:" + str_list[2])
print("Ch3:" + str_list[3])
print("CH4:" + str_list[4])
print("CH5:" + str_list[5])
print("CH6:" + str_list[6])
print("CH7:" + str_list[7])
print("CH8:" + str_list[8])
print("CH9:" + str_list[9])
print("気温" + str_list[16] + "℃")
print(" ")
#ログファイルに現在時刻を書き込む プロセスの稼働監視用
try:
file = open(filename, 'w')
lasttime = file.write(str(time.time()))
except Exception as e:
print(e)
finally:
file.close()
#気温センサが70度以上を示した場合、メール送信
if float(str_list[16]) > 70.0:
sendAlertMail(1, str_list[16], '')
#メール送信用メソッド
def sendAlertMail(reason, temperature, errorbody):
global sendmail
#メール送信は条件を満たしたとき1回のみ行う
if sendmail == 0:
smtp_server_host = '送信メールサーバ'
smtp_server_port = 送信メールサーバのポート番号
account = 'アカウント名'
password = 'パスワード'
from_email = 'メールアドレス'
msg = multipart.MIMEMultipart()
msg["Subject"] = "ラズピコ:通報メール"
msg["To"] = "メールアドレス"
msg["From"] = "メールアドレス"
if reason == 0:
msgstr = "ラズピコが停止しました" + str(temperature) + "℃ " + errorbody
elif reason == 1:
msgstr = "高温です " + str(temperature) + "℃ " + errorbody
elif reason == 999:
msgstr = "正常です " + str(temperature) + "℃ " + errorbody
else:
msgstr = "不明な事象が起こっています " + str(temperature) + "℃ " + errorbody
msg.attach(text.MIMEText(msgstr, 'plain', 'utf-8'))
server = smtplib.SMTP(smtp_server_host, smtp_server_port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(account, password)
server.send_message(msg)
server.close()
sendmail = 1
print("!!Send Mail!!")
def main():
while True:
_update()
if __name__ == '__main__':
main()
CT_mesurement.py(ラズピコ内のプログラム)
※一部HTML表示が崩れるため、全角文字を使っている部分あり
import machine
import utime
from machine import Pin, SPI
#動作している間はオンボードLEDを点滅させる
led_onboard = machine.Pin(25, machine.Pin.OUT)
#ラズピコ内蔵の温度センサを利用
sensor_temp = machine.ADC(4)
conversation_factor = 3.3 / (65535)
#CSピンを使うことで、1つのSPIバスで2つのADCを制御
cs1 = machine.Pin(5, machine.Pin.OUT)
cs2 = machine.Pin(14, machine.Pin.OUT)
cs1.value(1)
cs2.value(1)
#SPIの初期化
spi = SPI(0, baudrate=300000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(2), mosi=Pin(3), miso=Pin(4))
ite1 = 0
ite2 = 0
Vref = 2.447 #TL431の基準電圧(テスタ測定値)
Resistance = [42.2, 41.8, 50.5, 41.9, 41.9, 42.1, 42.0, 41.9, 50.8, 43.2, 43.8, 50.2, 50, 50, 50, 50] #各chの抵抗値(テスタ測定値)
sampling_count = 10000 #RMSをとるサンプリング数
moving_avg = 3 #移動平均区間
CT_ratio = [1866.662, 1792.035, 2238.42, 1870.499, 1865.004, 1849.13, 1781.08, 1849.199, 2231.249, 1842.651, 2000, 2000, 2000, 2000, 2000, 2000] #chごとの計測結果の補正
bias_voltage_bit10 = [445.5, 445.3, 445.8, 445.5, 445.7, 445.0, 445.1, 444.9, 445.5, 446.9, 445.9, 446.0, 0, 0, 0, 0] #各chのバイアス電圧の初期値
prev_bias_voltage_bit10 = []
CHNs = [0, 1, 2, 3, 4, 5, 6, 7]
#10bit ADC MCP3008の場合
read_buf = bytearray(3)
write_buf_mcp3008 = []
for i in CHNs:
write_buf_mcp3008.append(bytearray([0b00000001,
(0b00001000+CHNs[i]) << 4,
0b00000000]))
for i in range(16):
prev_bias_voltage_bit10.append([])
for j in range(moving_avg):
prev_bias_voltage_bit10[i].append(445)
adc_rawdata_sum = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
avg_voltage = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
avg_current = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
bit10_sum = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
while True:
for i in CHNs:
#ch0~7に対する処理
cs1.value(0)
spi.write_readinto(write_buf_mcp3008[i], read_buf)
cs1.value(1)
bit10_0 = ((read_buf[1] アンド 0b00000011) << 8) + read_buf[2]
adc_rawdata_sum[i] += ((((bit10_0 - bias_voltage_bit10[i])/1023)*Vref)**2) #ADCが読み取った値を瞬時電圧に変換し、2乗したものを加算
bit10_sum[i] += bit10_0
#ch8~15に対する処理
cs2.value(0)
spi.write_readinto(write_buf_mcp3008[i], read_buf)
cs2.value(1)
bit10_0 = ((read_buf[1] アンド 0b00000011) << 8) + read_buf[2]
adc_rawdata_sum[i+8] += ((((bit10_0 - bias_voltage_bit10[i+8])/1023)*Vref)**2)
bit10_sum[i+8] += bit10_0
ite1 = ite1 + 1
if ite1 > sampling_count - 1:
for i in CHNs:
#ch0~7に対する処理
avg_voltage[i] = (adc_rawdata_sum[i] / sampling_count) ** 0.5 #瞬時電圧の2乗の積算値から平均電圧を計算し、さらに平方根を計算(RMS)
avg_current[i] = (avg_voltage[i] / Resistance[i]) * CT_ratio[i] #電圧RMSから電流RMSを計算
adc_rawdata_sum[i] = 0
#バイアス電圧の移動平均処理
for j in range(1,moving_avg):
prev_bias_voltage_bit10[i][j-1] = prev_bias_voltage_bit10[i][j]
prev_bias_voltage_bit10[i][moving_avg-1] = bit10_sum[i] / sampling_count
bias_voltage_bit10[i] = sum(prev_bias_voltage_bit10[i]) / len(prev_bias_voltage_bit10[i])
bit10_sum[i] = 0
#ch8~15に対する処理
avg_voltage[i+8] = (adc_rawdata_sum[i+8] / sampling_count) ** 0.5
avg_current[i+8] = (avg_voltage[i+8] / Resistance[i+8]) * CT_ratio[i+8]
adc_rawdata_sum[i+8] = 0
for j in range(1,moving_avg):
prev_bias_voltage_bit10[i+8][j-1] = prev_bias_voltage_bit10[i+8][j]
prev_bias_voltage_bit10[i+8][moving_avg-1] = bit10_sum[i+8] / sampling_count
bias_voltage_bit10[i+8] = sum(prev_bias_voltage_bit10[i+8]) / len(prev_bias_voltage_bit10[i+8])
bit10_sum[i+8] = 0
print(avg_current) #ラズパイへ各chの電流値をシリアル送信
ite2 = ite2 + 1
ite1 = 0
led_onboard.toggle()
reading_temp = sensor_temp.read_u16() * conversation_factor #周囲温度を計算
temperature = 27 - (reading_temp - 0.706) / 0.001721
spi.deinit()