Measure resistance with INA226

Dependencies:   INA226 TextLCD mbed

Fork of INA226TEST by Toshihisa T

main.cpp

Committer:
Naoto_111
Date:
2016-05-15
Revision:
4:04014356c355
Parent:
3:1bd37786be90

File content as of revision 4:04014356c355:

/*前バージョンからの変更点
・シリアル通信モードでもオフセットの初期値を取得するように変更
・シリアル通信モードで最初に送られるデータが(0.0, 0.0, 0,0)だったのを、
センサから取得した値を送るように変更
*/
#include "mbed.h"
#include "TextLCD.h"
#include "INA226.hpp"
//#include "limits.h"

#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 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);

float resistance, offset;
bool detailmode = false;
volatile bool serialmode = false;

void gaugeOffset();//ゲージのオフセットを設定
void changeMode();//ゲージモードと測定値の詳細表示の切り替え
void isrRx();//受信イベント

unsigned short val;
double V,C;
int count = 1;

int main()
{
    pc.baud(115200);
    VCmonitor.rawWrite(0x00,0x4EDF);
    if(!VCmonitor.isExist()) {
        pc.printf("VCmonitor NOT FOUND\r\n");
        while(1) {}
    }
    pc.printf("VCmonitor FOUND\r\n");

    val = 0;
    if(VCmonitor.rawRead(0x00,&val) != 0) {
        pc.printf("VCmonitor READ ERROR\r\n");
        while(1) {}
    }
    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);
    }

    led[0] = led[1] = */
    resistance = offset = 0;
    if((VCmonitor.getVoltage(&V) == 0) && (VCmonitor.getCurrent(&C) == 0))
        offset = (float) 10*V/C;
    //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");

        float voltage = 0;
        for(int i = 0; i < SAMPLES; i++)voltage += sensor.read();
        voltage = voltage * 3.3 / SAMPLES;
        resistance = R1 / (VCC / voltage - 1);
        pc.printf("%f,%f,%f\n", voltage, resistance, offset);
        //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)分割

        led[0] = 1;
        led[1] = 0;

        //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);
                }
        */
        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)) {
                voltage = (float) V/1000;
                resistance = (float) 10*V/C;

            }
            //pc.printf("%f,%f,%f\n", 1.1, 200.0, 0.0);
            pc.printf("%f,%f,%f\n", voltage, resistance, offset);
            count++;
            break;

        case 'o'://offset
            offset = resistance;
            break;

        case 'q'://quit serial mode
            serialmode = false;
            return;
    }
}