Skip to content

Instantly share code, notes, and snippets.

@TakehikoShimojima
Created October 25, 2019 00:17
Show Gist options
  • Save TakehikoShimojima/4783521b0d15a808bb2852aa8d44801c to your computer and use it in GitHub Desktop.
Save TakehikoShimojima/4783521b0d15a808bb2852aa8d44801c to your computer and use it in GitHub Desktop.
/*
* PAC1710で10ミリ秒毎に1000回、10秒、電流値を測定し、SDカードに書く
*/
#include <M5Stack.h>
#include <Wire.h>
#include "PAC1710.hpp"
#include "menu.h"
void beep(int freq, int duration, uint8_t volume);
#define DEVID PAC1710::ADDR::OPEN // Resistor OPEN (N.C.) at ADDR_SEL pin
const int VSHUNT_mOHM = 10;
int sampling = 10; // サンプリング間隔(ミリ秒)
#define NSAMPLES 1000 // 10ms x 1000 = 10秒
float startthreshold = 20.0; // 記録を開始する電流値(ミリA)
void datasend(int id,int reg,int *data,int datasize) {
Wire.beginTransmission(id);
Wire.write(reg);
for(int i=0;i<datasize;i++) {
Wire.write(data[i]);
}
Wire.endTransmission();
}
int dataread(int id,int reg,int *data,int datasize) {
Wire.beginTransmission(id);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(id, datasize);
int i=0;
while((i<datasize) && Wire.available()) {
data[i] = Wire.read();
i++;
}
return Wire.endTransmission(true);
}
uint16_t getID() {
int id[2] = {0};
dataread(DEVID, PAC1710::REG::PID, id, 2);
return (id[0] << 8) | id[1];
}
#define TIMER0 0
hw_timer_t * samplingTimer = NULL;
float ampbuf[NSAMPLES];
float voltbuf[NSAMPLES];
Menu menu;
volatile int t0flag;
void IRAM_ATTR onTimer0() {
t0flag = 1;
}
#define X0 10
#define Y0 220
void drawData(float maxamp) {
M5.Lcd.fillRect(0, 0, 320, 220, BLACK);
for (int i = 0; i < 299; i++) {
int y0 = map((int)ampbuf[i * 3], 0, (int)maxamp, Y0, 0);
int y1 = map((int)ampbuf[(i + 1) * 3], 0, (int)maxamp, Y0, 0);
M5.Lcd.drawLine(i + X0, y0, i + 1 + X0, y1, WHITE);
}
M5.Lcd.drawLine(X0, Y0, 310, Y0, WHITE);
M5.Lcd.drawLine(X0, 0, X0, Y0, WHITE);
}
void setup() {
M5.begin();
pinMode(21, INPUT_PULLUP); // SDAをプルアップする
pinMode(22, INPUT_PULLUP); // SCLをプルアップする
Wire.begin();
M5.Lcd.setTextSize(2);
M5.Lcd.fillScreen(BLACK);
if (getID() != 0x585D) {
M5.Lcd.setCursor(20, 100);
M5.Lcd.print("Can not find PAC1710");
}
int c1cnf[] = {0B00110000}; // Sample time: 20ms, Range: -10mV to 10mV
datasend(DEVID, PAC1710::REG::C1_VSAMP_CFG, c1cnf, 1);
menu.setMenu("start", "", "");
M5.Lcd.setCursor(20, 100);
M5.Lcd.print("Press A button");
M5.Lcd.setCursor(40, 120);
M5.Lcd.print("to start sampling");
while (true) {
M5.update();
if (M5.BtnA.wasPressed()) break;
}
M5.Lcd.fillScreen(BLACK);
beep(2000, 100, 2);
samplingTimer = timerBegin(TIMER0, 80, true); // 1マイクロ秒のタイマーを初期設定する
timerAttachInterrupt(samplingTimer, &onTimer0, true); // 割り込み処理関数を設定する
timerAlarmWrite(samplingTimer, sampling * 1000, true); // samplingミリ秒のタイマー値を設定する
timerAlarmEnable(samplingTimer); // タイマーを起動する
bool started = false;
int indx = 0;
float maxamp = 0;
M5.Lcd.fillRect(50, 100, 200, 10, BLACK);
while (true) {
t0flag = 0;
while (t0flag == 0) { // タイマー割り込みを待つ
delay(0);
}
int ch1Vsense[2] = {0};
int ch1Vsource[2] = {0};
dataread(DEVID, PAC1710::REG::C1_SVRES_H, ch1Vsense, 2); // CHANNEL 1 VSENSE RESULT REGISTER
dataread(DEVID, PAC1710::REG::C1_VVRES_H, ch1Vsource, 2); // CHANNEL 1 VSOURCE RESULT REGISTER
float amp = ( (int16_t(ch1Vsense[0] << 8 | (ch1Vsense[1])) >>4) * (1000.0 / 2047));
float volt = (int16_t((ch1Vsource[0] << 3) | (ch1Vsource[1] >> 5) ) * 19.531);
if (!started) {
// 電流値がしきい値(startthreshold)未満だったら、測定を始めない
if (amp > -startthreshold && amp < startthreshold) {
continue;
}
started = true; // 電流値がしきい値を超えたら測定開始
}
ampbuf[indx] = amp; // 電流値をメモリーに記録する
voltbuf[indx] = volt; // 電圧値をメモリーに記録する
maxamp = max(amp, maxamp);
M5.Lcd.setCursor(100, 100);
M5.Lcd.print(indx * 100 / NSAMPLES); M5.Lcd.print(" %");
if (++indx >= NSAMPLES) { // データー数がサンプル数を超えたら、周期処理を終わる
break;
}
}
timerAlarmDisable(samplingTimer); // タイマーを停止する
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(20, 100);
beep(2000, 400, 2);
char fname[20];
sprintf(fname, "/curLog.csv");
for (int i = 0; SD.exists(fname); i++) {
sprintf(fname, "/curLog(%d).csv", i + 1);
}
File f = SD.open(fname, FILE_WRITE);
if (f) {
f.println("time, current(mA), volt(mV)");
for (int i = 0; i < NSAMPLES; i++) {
f.printf("%d, %.2f, %.2f\r\n", sampling * i, ampbuf[i], voltbuf[i]);
}
f.close();
M5.Lcd.print("Data written to");
M5.Lcd.setCursor(40, 120);
M5.Lcd.print(fname);
} else {
M5.Lcd.printf("open error %s", fname);
}
menu.setMenu("view", "", "");
M5.Lcd.setCursor(40, 160);
M5.Lcd.print("Press A button");
M5.Lcd.setCursor(40, 180);
M5.Lcd.print("to view data");
while (true) {
M5.update();
if (M5.BtnA.wasPressed()) {
drawData(maxamp);
}
}
}
void loop() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment