Measure resistance with INA226

Dependencies:   INA226 TextLCD mbed

Fork of INA226TEST by Toshihisa T

Revision:
2:d3723c3e869b
Parent:
0:b20f8673a7fa
Child:
3:1bd37786be90
--- a/main.cpp	Sat Nov 24 18:38:51 2012 +0000
+++ b/main.cpp	Sat May 14 00:51:05 2016 +0000
@@ -1,48 +1,231 @@
-/*
- * Copyright (c) 2011 Toshihisa T
- * Released under the MIT License: http://mbed.org/license/mit
- */
+/*前バージョンからの変更点
+・INA226のAveraging modeと同じような機能を実装
+・シリアル通信モードからテキストディスプレイモードに戻れるようにした
+(qキーを押すことで使用可)
+*/
+#include "mbed.h"
+#include "TextLCD.h"
+#include "INA226.hpp"
+//#include "limits.h"
 
-#include "mbed.h"
-#include "INA226.hpp"
+#define VCC 3.3//抵抗R1に供給する電圧[V]
+#define R1 10000.0//抵抗R1の値[Ω]
+#define GAUGE_STEP 17//テキストディスプレイモード:ゲージの段階数
+#define GAUGE_MAX 100.0//テキストディスプレイモード:ゲージ最大状態の値[Ω]
+#define GAUGE_NOTIFY 50.0//テキストディスプレイモード:音を鳴らし始める値[Ω]
+#define INTERVAL_SERIAL 0.5//シリアル通信モード:データを収集する間隔[秒]
+#define INTERVAL_TEXTLCD 0.1//テキストディスプレイモード:データを収集する間隔[秒]
+#define SAMPLES 10//一回の測定で取得するデータの数(これらのデータの平均を使用)
 
-Serial debug(USBTX,USBRX);
-DigitalOut myled(LED1);
+Serial pc(USBTX,USBRX);//tx,rx :シリアル通信
+TextLCD dsp_t(p24, p23, p22, p19, p21, p20);// rs, e, d4-d7 :テキストディスプレイ
+//LocalFileSystem local("local");//内部ストレージ
+AnalogIn sensor(p18);
+InterruptIn setoffset(p17);//テキストディスプレイモード:オフセット設定
+InterruptIn mode(p16);//テキストディスプレイモード:ゲージ←→数値詳細  切替
+PwmOut speaker(p25);
+//Timer tim;
+DigitalOut led[] = {LED1, LED2};
 I2C i2c(p28,p27);
 INA226 VCmonitor(i2c);
 
-int main() {
-    unsigned short val;
-    double V,C;
-    int count = 1;
+float resistance, offset;
+bool detailmode = false;
+volatile bool serialmode = false;
+
+void gaugeOffset();//ゲージのオフセットを設定
+void changeMode();//ゲージモードと測定値の詳細表示の切り替え
+void isrRx();//受信イベント
 
-    debug.format(8,ParityNone,1);
-    debug.baud(115200);
-    debug.printf("VCmonitor INA226 TEST Program. (BUILD:[" __DATE__ "/" __TIME__ "])\n");
+unsigned short val;
+double V,C;
+int count = 1;
 
+int main()
+{
+    pc.baud(115200);
+    VCmonitor.rawWrite(0x00,0x4EDF);
     if(!VCmonitor.isExist()){
-        debug.printf("VCmonitor NOT FOUND\n");
+        pc.printf("VCmonitor NOT FOUND\r\n");
         while(1){}
     }
-    debug.printf("VCmonitor FOUND\n");
+    pc.printf("VCmonitor FOUND\r\n");
 
     val = 0;
     if(VCmonitor.rawRead(0x00,&val) != 0){
-        debug.printf("VCmonitor READ ERROR\n");
+        pc.printf("VCmonitor READ ERROR\r\n");
         while(1){}
     }
-    debug.printf("VCmonitor Reg 0x00 : 0x%04x\n",val);
+    pc.printf("VCmonitor Reg 0x00 : 0x%04x\r\n",val);
+
+    VCmonitor.setCurrentCalibration(0x0800);
+    /*tim.start();
+    led[0] = led[1] = 1;
+
+    while(serialmode == false && tim.read() < SERIAL_WAIT) {
+        if(pc.readable()) {//通信相手からデータが送られてきた時
+            serialmode = true;
+            break;
+        }
+        wait(0.5);
+    }
 
-    VCmonitor.setCurrentCalibration();
+    led[0] = led[1] = */resistance = offset = 0;
+    //tim.stop();
+    //FILE *fp = NULL;
+    pc.attach(isrRx,Serial::RxIrq);//割り込みハンドラ登録
+BUNKI:
+    if(serialmode == true) {//シリアル通信モード
+        led[0] = 0;
+        led[1] = 1;
+        //if(fp!=NULL)fclose(fp);
+        dsp_t.cls();
+        dsp_t.printf("Serial mode");
+        pc.printf("%f,%f,%f\n", 0.0, 0.0, 0.0);
+        while(1){
+            if(serialmode == false)goto BUNKI;
+        }
+    } else {//テキストディスプレイモード
+        
+        float t = 1.0/261.626;//「ド」の音(C4)の周期
+        float a = (t-(t/2/2))/GAUGE_MAX;//C4の周期と2オクターブ上の音の周期の差を(GAUGE_MAX)分割
 
-    while(1) {
+        led[0] = 1;
+        led[1] = 0;
         if((VCmonitor.getVoltage(&V) == 0) && (VCmonitor.getCurrent(&C) == 0)){
-            debug.printf("%d,V,%f,C,%f\n",count,V,C);
+                offset = 10*V/C;
+        }
+        //offset = R1 / (VCC / (sensor.read() * 3.3)- 1);//オフセット初期値の取得
+        speaker = 0.0;
+
+        speaker.period(0.001);
+        //tim.reset();
+        //tim.start();
+        setoffset.rise(&gaugeOffset);//割り込みハンドラ登録
+        mode.rise(&changeMode);//割り込みハンドラ登録
+
+/*
+        if((fp = fopen("/local/data.txt", "r")) != NULL) { //data.txtの検出
+            if(fgetc(fp)!=EOF) {
+                dsp_t.printf("Err:data exists\nPlease move it.");
+                return EXIT_FAILURE;
+            }
+            fclose(fp);
         }
-        myled = 1;
-        wait(0.5);
-        myled = 0;
-        wait(0.5);
-        count++;
+*/
+        while(1) {
+            if(serialmode == true)goto BUNKI;
+            /*
+            static unsigned long long int time_sum = 0;
+            int now = tim.read_ms();
+            if(now > 1800000) {
+                time_sum += now;
+                tim.reset();
+            }
+            if(time_sum > ULLONG_MAX - 10000000) {
+                printf("Err:time out\nPlease restart now.");
+                return EXIT_FAILURE;
+            }*/
+            float voltage = 0.0;
+            for(int i = 0; i < SAMPLES; i++)voltage += sensor.read();
+            voltage = voltage * 3.3 / SAMPLES;
+            resistance = R1 / (VCC / voltage - 1);
+            //if((fp = fopen("/local/data.txt", "a")) == NULL)return EXIT_FAILURE;
+            //fprintf(fp, "%lld %f %f %f\r\n", now + time_sum, voltage, resistance, offset);
+            //fclose(fp);
+            if((VCmonitor.getVoltage(&V) == 0) && (VCmonitor.getCurrent(&C) == 0)){
+                voltage = V/1000;
+                resistance = 10*V/C;
+            }
+            dsp_t.cls();
+            if(detailmode == false) {
+                for(int i = 0; i < (int)((resistance - offset) / (GAUGE_MAX / GAUGE_STEP)) && i < GAUGE_STEP; i++)
+                    dsp_t.printf("%c", 0xFF);//ゲージ
+
+                dsp_t.locate(0, 1);
+
+                if(resistance>=1000000000)dsp_t.printf("R=%3.0fG%c", resistance/1000000000,0xF4);
+                else if(resistance>=1000000)dsp_t.printf("R=%3.0fM%c", resistance/1000000,0xF4);
+                else if(resistance>=1000)dsp_t.printf("R=%3.0fk%c", resistance/1000,0xF4);
+                else dsp_t.printf("R=%4.0f%c", resistance,0xF4);
+
+                if(offset>=1000000000)dsp_t.printf("  O=%3.0fG%c", offset/1000000000,0xF4);
+                else if(offset>=1000000)dsp_t.printf("  O=%3.0fM%c", offset/1000000,0xF4);
+                else if(offset>=1000)dsp_t.printf("  O=%3.0fk%c", offset/1000,0xF4);
+                else dsp_t.printf("  O=%4.0f%c", offset,0xF4);
+            } else {
+                if(resistance>=1000000000)dsp_t.printf("R=%11.7f G%c", resistance/1000000000,0xF4);
+                else if(resistance>=1000000)dsp_t.printf("R=%11.7f M%c", resistance/1000000,0xF4);
+                else if(resistance>=1000)dsp_t.printf("R=%11.7f k%c", resistance/1000,0xF4);
+                else dsp_t.printf("R=%11.7f  %c", resistance,0xF4);
+
+                dsp_t.locate(0, 1);
+
+                if(offset>=1000000000)dsp_t.printf("O=%11.7f G%c", offset/1000000000,0xF4);
+                else if(offset>=1000000)dsp_t.printf("O=%11.7f M%c", offset/1000000,0xF4);
+                else if(offset>=1000)dsp_t.printf("O=%11.7f k%c", offset/1000,0xF4);
+                else dsp_t.printf("O=%11.7f  %c", offset,0xF4);
+            }
+
+            speaker = 0.5;
+            if(resistance - offset >= GAUGE_NOTIFY)speaker.period(t-a*(resistance - offset));
+            else speaker = 0.0;
+            wait(INTERVAL_TEXTLCD);
+        }
     }
 }
+
+void gaugeOffset()
+{
+    speaker.period(0.01);
+    speaker = 0.5;
+    if(detailmode == false) {
+        dsp_t.locate(0, 0);
+        dsp_t.printf("################");
+    }
+    offset = resistance;
+    wait(0.5);
+    dsp_t.cls();
+    speaker = 0.0;
+    //speaker.period(0.001);
+}
+
+void changeMode()
+{
+    detailmode = (detailmode == false) ? true : false;
+}
+
+
+void isrRx()
+{
+    if(serialmode == false){
+        serialmode=true;
+        return;
+    }
+    char ch;
+    //static float resistance = 0, offset = 0;
+    ch = pc.getc();
+
+    switch(ch) {
+
+        case 'c'://continue
+            float voltage = 0;
+            //for(int i = 0; i < SAMPLES; i++)voltage += sensor.read();
+            //voltage = voltage * 3.3 / SAMPLES;
+            //resistance = R1 / (VCC / voltage - 1);
+            if((VCmonitor.getVoltage(&V) == 0) && (VCmonitor.getCurrent(&C) == 0)){
+                //pc.printf("%d %fV , %fmA , R %f\r\n",count,V/1000,C/10,10*V/C);
+                pc.printf("%f,%f,%f\n", V/1000, 10*V/C, offset);
+            }
+            count++;
+            break;
+
+        case 'o'://offset
+            offset = resistance;
+            break;
+            
+        case 'q'://quit serial mode
+            serialmode = false;
+            return;
+    }
+}