ILF / Mbed 2 deprecated mbed_ILF

Dependencies:   mbed SDFileSystem

ILF3_rev1.cpp

Committer:
arthurjapan
Date:
2022-05-09
Revision:
13:e138a91ed2cb
Parent:
10:b34306f7add6

File content as of revision 13:e138a91ed2cb:

#include "mbed.h"
#include "SDFileSystem.h"


//difine_mbed_LPC1768

/*******************************************************************************

2022.4.8
ILF V3 Iop汎用器

ver3.0.0 2022.4.8 tanaka
    mbed_ILF ver1.2.5を引継ぎ
    ILF3のハードに合せて改編する
    
    1.EEPROMの変更 ONsemi製CAT24M01WI-GT3
        the CAT24M01 is a 1024kb serial CMOS EEPROM
        addres: 101010**

    2.電圧測定の平均化



******************************************************************************/
/*
仕様
電圧/抵抗測定:12bit
電流測定:14bit

割込みはP0~P2で可能
シーケンサスタート信号は、回路図「seq_yobi]で対応

ver1.2.5
IOP測定値にO.L追加 ±100uA

ver1.2.4
ver1.2.3のDEB_EN=0としたもの。
公開用。

ver1.2.3
EEPROM通信のコードを修正。
debug mode の追加

ver1.2.2
過充電防止検査の上限規格の判定追加
CAL情報登録画面において、登録項目の順序入替え(過充電防止上限規格の挿入)
過充電防止上限規格ゼロの場合、判定しない

ver1.2.1
過充電防止検査の上限規格を新たに設置。
それに伴い、規格値のメモリ割り当てと、上限規格設定画面を追加。

ver1.2.0

2021.9.7

CAL.LJ21(A1098A05)専用
発電検出時、高照度条件下でVSS電圧がIC耐圧超える為、VHD-VDD短絡する仕様へ変更(A05)
200lx下でもVHD-VDD短絡の電圧条件を満たす為、ILFも対応。
VSS端子でVOC測定をする。その為、VOC測定時以外はVSS端子と測定器を切り離すリレーを
サブ基板へ取り付け、制御プログラムを追加した。
CH1:P1_23(LPC1768) (led3_on)
CH2:P1_22(LPC1768) (led3_off)

アンテナ測定時にアンテナ測定端子切り離し用リレーのON/OFF制御を追加
(led4_on)
(led4_off)

ver1.1.0
1)VFD_SW23 SW31がタッチ感度故障の為、配置替え
CAL登録画面とMANUAL測定画面
2)DELETE EEPROM ボタンの配置変更
3)シーケンサ判定IOの変更

ver1.1.1
void auto_meas において初期 R[i]の値をクリアすることを追加
自動測定時、タッチパネルでスタートをやめる(外部IO入力のみ)

ver1.1.2
過充電防止検査時の電源電圧:VOC検査時の電圧となっていたのを修正。

ver1.1.3
1)SDカード未挿入の表示を削除

2)R=Hの時間を0.2sから1sへ変更

R5186 ver2.0.3の内容を反映。

未)フラグでR5186系と切替え
未)測定部ごとにクラス分け(過充電防止のところだけでも)

*******************************************************************************/
//
//定数
//
//soft ver
const int version_major = 3;
const int version_minor = 0;
const int version_build = 0;

const char pass[] = "ILF";      //password(大文字)
#define YOSO            3       //password文字数

#define O_L             100     //[uA]電流測定値のオーバーロード値 //ver1.2.5
/*
#define CAP             20      //[uF] 積分回路のコンデンサ容量
#define TIME_INT        2       //[s]積分時間
#define GAIN_I          0.2     //電流測定プリアンプのGAIN
#define LSB_I           0.00025 //[V] MCP3424 LSB size of 14bit conversion rate setting 
#define MINCODE_I       -8192   //Minimum output code of MCP3424
#define MAXCODE_I       8191    //Maximum output code of MCP3424
#define GAIN_V          0.2     //電流測定プリアンプのGAIN
*/
#define DEB_EN          0       //デバッグイネーブル:1 ディスイネーブル:0 ver1.2.3
#define RL_EN           0       //1:io[]を外付けのリードリレー制御用に使用する場合は1.以外は0. ver1.2.3
#define SEQ_EN          0       //1:シーケンサ接続仕様 0:シーケンサ未接続仕様
#define period_pwm      200     //*us
#define COP             0.0039  //pwm_duty(%) = COP * DATA(0~255) ver3 0.005 -> 0.0039
#define rsense          1000    //抵抗測定回路のプルアップ抵抗値 1kΩ
#define res_vref        0x800   //抵抗測定回路のリファレンス電圧 2.048V
#define dac_vref        2500    //DACのリファレンス電圧 単位[mV]
#define number_of_channels   4  //測定チャンネル数(MAX 4)
#define time_discharge  0.5     //discharging time(s)
#define time_integral   2       //integral time(s)
#define wait_voc_1      0.5     //[s]VOC測定電圧設定後からリセットまでの時間
//#define wait_reset      0.3     //[s]リセット解除からVOC測定までの時間
#define wait_poweron    4       //[s]電源投入からリセットまでの時間
#define time_reset      0.5     //reset Hの時間 ver1.1.3
#define TIME_RELAY_ON   0.5     //外付けリードリレー用 Ton[s]
#define TIME_RELAY_OFF  0.2     //外付けリードリレー用 Toff[s]
const int ton_rr = 0.1;         //内蔵リードリレー ton[s]
const int toff_rr = 0.1;        //内蔵リードリレー toff]
const bool tenken = true;       //日常点検用 マニュアルモードにて True:測定CHのみVSS出力 False:全CH,VSS出力

//Display
#define touch           5                   //GU-D タッチパネル感度 0~7で設定。低いほど敏感。
const char sw_up_set[] = {20,21,22,23};     //CAL情報セット画面におけるUPスイッチの表示位置番号
const char sw_down_set[] = {28,29,30,31};   //CAL情報セット画面におけるDOWNスイッチの表示位置番号
const int zahyou_para1[] = {0,2};       //CAL情報セット画面における項目の表示位置座標
const int zahyou_para2[] = {0,4};       //CAL情報セット画面における項目の表示位置座標
const int zahyou_val[] = {96,4};       //CAL情報セット画面における数値の表示位置座標
const int zahyou_unit[] = {160,4};     //CAL情報セット画面における単位の表示位置座標
const char *cpara1[]= {
    "IOP",      //x=0  : vss_iop[V]
    "OCP",      //x=1  : vss_ocp[V]
    "VOC",      //x=2  : vss_voc[V]
    "VOC",      //x=3  : low_limit_voc[V]
    "IOP",      //x=4  : low_limit_iop[uA]
    "OCP",      //x=5  : low_limit_ocp[uA]
    "OCP",      //x=6  : up_limit_ocp[uA]
    "OCP",      //x=7  : low_limit_ocp_v[V]
    "OCP",      //x=8  : up_limit_ocp_v[V]
    "IOP",      //x=9  : wait_iop[s]
    "OCP",      //x=10 : wait_ocp[s]
    "VOC",      //x=11 : wait_voc[s]
    "ANTENA",   //x=12 : low_limit_resistor[Ω]
    "ANTENA",   //x=13 : up_limit_resistor[Ω]
    ""          //x=14 : cal_name(ASCII)
};
const char *cpara2[]= {
    "VSS",              //x=0  : vss_iop[V]
    "VSS",              //x=1  : vss_ocp[V]
    "VSS",              //x=2  : vss_voc[V]
    "LOW LIMIT",        //x=3  : low_limit_voc[V]
    "LOW LIMIT",        //x=4  : low_limit_iop[uA]
    "LOW LIMIT",        //x=5  : low_limit_ocp[uA]
    "UP  LIMIT",        //x=6  : up_limit_ocp[uA]
    "LOW LIMIT",        //x=7  : low_limit_ocp_v[V]
    "UP  LIMIT",        //x=8  : up_limit_ocp_v[V]
    "WAIT",             //x=9  : wait_iop[s]
    "WAIT",             //x=10 : wait_ocp[s]
    "WAIT",             //x=11 : wait_voc[s]
    "LOW LIMIT",        //x=12 : low_limit_resistor[Ω]
    "UP  LIMIT",        //x=13 : up_limit_resistor[Ω]
    "NAME"                  //x=14 : cal_name(ASCII)
};
const char *cunit[]= {
    "V",                //x=0  : vss_iop[V]
    "V",                //x=1  : vss_ocp[V]
    "V",                //x=2  : vss_voc[V]
    "V",                //x=3  : low_limit_voc[V]
    "uA",               //x=4  : low_limit_iop[uA]
    "uA",               //x=5  : low_limit_ocp[uA]
    "uA",               //x=6  : up_limit_ocp[uA]
    "V",                //x=7  : low_limit_ocp_v[V]
    "V",                //x=8  : up_limit_ocp_v[V]
    "s",                //x=9  : wait_iop[s]
    "s",                //x=10 : wait_ocp[s]
    "s",                //x=11 : wait_voc[s]
    "",                //x=12 : low_limit_resistor[Ω]
    "",                //x=13 : up_limit_resistor[Ω]
    ""                  //x=14 : cal_name(ASCII)
};

/*
x=0  : vss_iop[V]
x=1  : vss_ocp[V]
x=2  : vss_voc[V]
x=3  : low_limit_voc[V]
x=4  : low_limit_iop[uA]
x=5  : low_limit_ocp[uA]
x=6  : up_limit_ocp[uA]
x=7  : low_limit_ocp_v[V]
x=8  : up_limit_ocp_v[V]
x=9  : wait_iop[s]
x=10 : wait_ocp[s]
x=11 : wait_voc[s]
x=12 : low_limit_resistor[Ω]
x=13 : up_limit_resistor[Ω]
x=14 : cal_name(ASCII)
*/


/*******************************************************************************

    LPC1768 PIN MAPPING

*******************************************************************************/
//繰り返しタイマー割り込み
Ticker flipper; /* 初期化 */
//one shot timer
Timeout oneshot1;
Timeout oneshot2;
Timeout oneshot3;
Timeout oneshot4;
Timeout oneshot5;//CAL番号未送信タイムアウト用

/*** SD-CARD ***/
SDFileSystem sd(P0_9, P0_8, P0_7, P0_6, "sd"); //SDFileSystem name(mosi, miso, sck, cs, mount);

/*** I2C ***/
I2C i2c(P0_10,P0_11); //(PinName sda, PinName scl) I2Cを定義

/*** UART ver3 ***/
//RawSerial uart(P0_15,P0_16,19200);
//RawSerial pc(USBTX,USBRX,9600); //mbed⇔PCデバック用
RawSerial pc(P0_15,P0_16,19200);//ILF3⇔PCデバック用

/*** interruput ***/
//InterruptIn seq_yobi(P0_19);

/*** start sw ***/
DigitalIn sw_start(P0_4);

/*** DigitalOut ***/
DigitalOut  houden[]  = {  //  配列を用意します
    DigitalOut( P2_1 ),  //houden1 配列の1番目の要素を**で初期化したDigitalOutに
    DigitalOut( P2_0 ),  //houden2
    DigitalOut( P1_28 ), //houden3
    DigitalOut( P1_29 )  //houden4
};

DigitalOut  io[]  = { 
    DigitalOut( P2_11 ),  //io1
    DigitalOut( P2_12 ),  //io2
    DigitalOut( P1_18 ),  //io3
    DigitalOut( P1_19 ),  //io4
    DigitalOut( P0_17 ),  //io5
    DigitalOut( P0_18 ),  //io6
    DigitalOut( P1_30 ),  //io7
    DigitalOut( P1_31 ),  //io8
    DigitalOut( P1_22 ),  //io9
    DigitalOut( P1_23 ),  //io10
    DigitalOut( P1_24 ),  //io11
    DigitalOut( P1_25 ),  //io12
    DigitalOut( P0_23 ),  //io13
    DigitalOut( P0_24 ),  //io14
    DigitalOut( P0_25 ),  //io15
    DigitalOut( P0_26 )   //io16
};

DigitalOut io_reset[] = {
    DigitalOut( P1_22 ),  //io9
    DigitalOut( P1_23 ),  //io10
    DigitalOut( P1_24 ),  //io11
    DigitalOut( P1_25 ),  //io12
};

/*
DigitalOut  io[]  = {  //  配列を用意します
    DigitalOut( P0_25 ),  //io1 配列の1番目の要素をP0_25で初期化したDigitalOutに
    DigitalOut( P0_26 ),  //io2
    DigitalOut( P0_23 ),  //io3
    DigitalOut( P0_24 ),  //io4
    DigitalOut( P1_22 ),  //io5
    DigitalOut( P1_23 ),  //io6
    DigitalOut( P1_24 ),  //io7
    DigitalOut( P1_25 )   //io8
};
*/

DigitalOut  range[] = {  //  配列を用意します
    DigitalOut( P2_3 ),  //range1 配列の1番目の要素を**で初期化したDigitalOutに
    DigitalOut( P2_2 ),  //range2
    DigitalOut( P1_26 ), //range3
    DigitalOut( P1_27 )  //range4
};

DigitalOut  led_green[] = {
    DigitalOut( P0_17 ),
    DigitalOut( P1_31 ),
    DigitalOut( P2_11 ),
    DigitalOut( P1_18 )
};

DigitalOut  led_red[] = {
    DigitalOut( P0_18 ),
    DigitalOut( P1_30 ),
    DigitalOut( P2_12 ),
    DigitalOut( P1_19 )
};

/*** PLC ver3 ***/
DigitalIn seq_in[] = {
    DigitalIn(P0_19),   //si1
    DigitalIn(P2_9),    //si2
    DigitalIn(P2_13),   //si3
    DigitalIn(P4_28),   //si4
    DigitalIn(P0_29),   //si5
    DigitalIn(P0_30)    //si6
};

DigitalOut seq_out[] = {
    DigitalOut( P0_21 ),    //so1
    DigitalOut( P0_22 ),    //so2
    DigitalOut( P3_25 ),    //so3
    DigitalOut( P3_26 ),    //so4
    DigitalOut( P0_20 ),    //so5
    DigitalOut( P2_6 ),     //so6
    DigitalOut( P2_7 ),     //so7
    DigitalOut( P2_8 )      //so8
};

//ver1.1.0
/*
DigitalOut  seq_hantei[] = {
    DigitalOut( P0_21 ),
    DigitalOut( P0_22 ),
    DigitalOut( P3_25 ),
    DigitalOut( P3_26 )
};

DigitalOut  seq_busy(P0_20);
//DigitalIn
DigitalIn   seq_start(P4_28);
DigitalIn   seq_cal_a(P2_6);
DigitalIn   seq_cal_b(P2_7);
DigitalIn   seq_cal_c(P2_8);
DigitalIn   seq_kosuu_a(P2_13);
DigitalIn   seq_kosuu_b(P2_9);
//DigitalIn   seq_yobi(P0_19);
*/

/*** PWM ***/
PwmOut leds[] = {   //配列を用意
    PwmOut(P2_5),  //LED1
    PwmOut(P2_4),  //LED2
    PwmOut(P1_21), //LED3
    PwmOut(P1_20)  //LED4
};

//RELAY ver3.0.0
DigitalOut  rlen[]  = { 
    DigitalOut( P1_4 ),     //RLCNT1
    DigitalOut( P1_8 ),     //RLCNT2
    DigitalOut( P1_9 ),     //RLCNT3    
    DigitalOut( P1_10 ),     //RLCNT4
    DigitalOut( P1_14 ),     //RLCNT5
    DigitalOut( P1_15 ),     //RLCNT6
    DigitalOut( P1_16 ),     //RLCNT7
    DigitalOut( P1_17 ),     //RLCNT8
};

/*******************************************************************************

    SD Card
 
*******************************************************************************/
void sd_writetext(char* text);

/*******************************************************************************

    gu-D(表示器) addr:50H

*******************************************************************************/
//parameter_gu256X128C-D903M
const   int addr_gu = 0x50 << 1; // Address of gu256X128C-D903M
//
//prototype
const int Proportional1 = 0x02;
//const int Proportional2 = 0x03;
//const int Proportional3 = 0x04;
//
void gu_cls();
void gu_drawButton(int x, int y, int w, int h, const char *data);
void gu_cursor(int x, int y);
void gu_fontsize(const char code);
void gu_print_dot(int x, int y, const char *ptext);
void gu_fontWidth(const char fontWidth);
void gu_print(const char t[] );
void gu_fontReverse(int code);
void gu_RealTimeImage_dot(int x, int y, int w, int h, const char data[]);
void gu_RealTimeImage(int w, int h, char data[]);
void gu_magnify(int x, int y);
//
//オリジナルgu用関数
void gu_print1(const char* ptext);
void gu_luminance(const char* cl);
void gu_touchPara(int x,int y);
void gu_sendOneByte(char data);
void utility(); //輝度調整サブルーチン
void gu_CRLF();
void gu_reverse(char x);
void gu_drawbutton_cursor(char x,char y);
void gu_onebyte(char data);
//
//Button Trig Function
void adjust_illumination();//LED輝度調整サブ
void gu_initial();//初期設定サブ
void gu_set_button(char sw_num,char* text);//SWナンバーと表示テキストを指定
void gu_set_button_font1(char sw_num,char* text);//fontsize = 1
void gu_button_up(char sw_num); //upボタン表示
void gu_button_down(char sw_num);//downボタン表示
void gu_Button_up1();
void gu_Button_up2();
void gu_Button_up3();
void gu_Button_up4();
void gu_button_up_on(char sw_num);
void gu_Button_up_on2();
void gu_Button_down1();
void gu_Button_down2();
void gu_Button_down3();
void gu_Button_down4();
void gu_button_down_on(char sw_num);
void gu_Button_down_on2();
void gu_Button_power_on();
void gu_Button_power_off();
//
/*******************************************************************************

    表示関数

*******************************************************************************/
void    select_cal();   //CAL選択画面
void    setup_cal_information(char cal_num);    //CAL情報登録画面
void    manual_int_hyouji();
void    auto_int_hyouji();
void    disp_setup_cal(char cal_num ,int parameter);   //CAL情報登録画面表示
//
//******************************************************************************

//    CAT24M01(EEPROM)
//      ver3.0.0 2022.4.8 

const static int eeprom_adrs = 0xA8;      //0x2A << 2 Address of PCAS08A(EEPROM) 6/8bit

int     slave_adrs;                //i2c slave address 8bit

char    rdata[17];                  //EEPROMからのリードデータ
char    wdata[17];                  //EEPROMへのライトデータ
int     Jyushin;                    //受信成功時 Jyushin=0
int     Soushin;                    //送信成功時 Soushin=0

const static char adrs_kido[]={0x00,0x00};      //VFDの輝度
const static char adrs_syoudo[]={0x00,0x10};    //測定用LED照度の値を保存しているアドレス
const static char adrs_calnum[]={0x00,0x20};    //CPUにロードしているCALの登録番号
const static char adrs_calinfo[]={0x01,0x00};   //CAL情報 0x0100~0x032FFを割り当て。1page256byte。No.1~No.50まで登録
//
//    CAL情報登録 -> EEPROM
//
#define     caliber_number  50       /* CAL登録数 */
//
//
/*******************************************************************************

    LCP1768(EEPROM) addr:15H

*******************************************************************************/
//parameter_PCAS08A(EEPROM)
//const   int addr_EEPROM = 0x15 << 3; // Address of PCAS08A(EEPROM) コメント化 ver1.2.1
//char    rdata[17]; //EEPROMからのリードデータ
//char    wdata[17]; //EEPROMへのライトデータ
//int     Jyushin; //受信成功時 Jyushin=0
//int     Soushin; //送信成功時 Soushin=0
//const   int eeprom_adrs = 0x15 << 3; // Address of PCAS08A(EEPROM) 始めの5bit ver1.2.1
//int     slave_adrs; //slave address ver1.2.1
//
/*******************************************************************************
    
    MCP3424(ADC)

    RESOLUTION SETTINGS VS. LSB
     -----------------------------------
    |Resolution Setting  |   LSB        |
     -----------------------------------
    |    12bits(00)      |   1mv        |
    |    14bits(01)      |   250uV      |
    |    16bits(10)      |   62.5uV     |
    |    18bits(11)      |   15.625uV   |
     -----------------------------------

*******************************************************************************/
//parameter_ADC(MCP3424)
const   int addr_ADC1 = 0x6C <<1;//電圧抵抗測定No.1,No.2用ADC
const   int addr_ADC2 = 0x6A <<1;//電圧抵抗測定No.3,No.4用ADC
const   int addr_ADC3 = 0x68 <<1;//電流測定No.1,No.2
const   int addr_ADC4 = 0x6E <<1;//電流測定No.3,No.4
//
char hd[] = "0123456789ABCDEF" ;
//
//関数
void    general_call(char com); //power on reset
char    adc_config(char ch, char rate);
//
/*******************************************************************************

    AD5625RBUZ(DAC) addr:1F

*******************************************************************************/
const   char addr_dac = 0x1F <<1;
void    dac_out(short mvolt, char addr);
void    dac_init();
//
/*******************************************************************************

    測定関係関数

*******************************************************************************/
void    set_pullup();//シーケンサからの入力ピンのプルアップ設定
void    trigger();//シーケンサからのスタート信号割込みサブ
void    calibration();
void    compute_adc(int adc_con, long *avg);//(ADCのCONFIG, 計算結果)
void    gu_putdec(short* x);//2byteを10進で表示
void    gu_putdeck(short* x);//2byteを10進で表示。1/1000.
void    gu_putdeci(float* x);// ver1.1.4
void    gu_putdeci_mA(float* x);// ver1.1.4
void    meas_current_automode(char amount);//AutoMOdeの電流測定サブ iop ocp共通
void    auto_run();//自動測定モード
void    auto_meas(char noc);//一括測定。ch:測定する総チャンネル数
void    meas_sub();//自動測定モード内の繰り返し処理
void    manual();//手動測定モード
void    hantei(char noc);//規格値比較エラーフラグ立てる
void    select_ich(char ch);//電流測定chの選択と設定
short   read_adc(char addr);//指定addressから2byte読込み
short   meas_voltage(char ch);//測定チャンネルを指定して、測定値(2byte)を返す
short   meas_resistor(char ch);//測定チャンネルを指定して、測定値(2byte)を返す
void    display_resistor(short sdata);//測定値を表示する。
void    led_off();//判定用LED全消灯
void    read_syoudo(char* c);//EEPROMから照度データ(PwmDuty)を読み込んでセットする
void    seq_serialsend(/*int noc*/);//シーケンサへのシリアル出力
void    seq_serialrecive(/*int noc*/);//シーケンサへのシリアル入力
void    seq_timeout();//シーケンサからCAL番号が一定時間出力されなければ前回のCAL番号で測定


/*******************************************************************************

    測定関係 変数
    
*******************************************************************************/
char    io_voc; //VOC測定時のIO操作。ON(=VDD)の場合は”0x01"OFF(=OPEN)は"0x00"
char    err_f[4];//ch1~4 規格外発生時のフラグ 0or1
short   V[4];//ADC入力値を3倍した値 測定値[V] 16進数
float   I[4];//電流測定値チャンネル毎の
short   R[4];//抵抗測定値
short   voc[4];//ADC入力値を3倍した値 測定値[mV] 16進数
double  vocp[4];//過充電防止時のHD測定電圧
float   iop[4];//2byte 補数あり 測定値 1bit 0.01uA
float   ocp[4];//2byte 補数あり 測定値
char    ch_num ;//選択中の測定チャネル(0~3)
int     cat;//検査カテゴリNo.
float   fdata[4][4];//ファイル出力用
char    seq_name[4] = {0,0,0,0};//CAL番号一時格納用配列


//structure
struct cal_info {
    char    name[4];            // CAL NAME ASCII CODE ver3
    short   number;             // CAL.No.
    short   vss_iop;            // IOP測定時のVss電圧 1bit * 0.01uA
    short   vss_ocp;            // 過充電防止(over charge protection)測定時のVss電圧
    short   vss_voc;            // VOC測定時のVss電圧
    short   low_limit_voc;      // 1bit * 1mv
    short   low_limit_iop;      // 1bit * 0.01uA
    short   low_limit_ocp;      // 過充電防止検査の下規格値(プラス側)
    short   up_limit_ocp;       // 過充電防止検査の上限規格値(マイナス側)ver1.2.1追加
    float   wait_iop;           // Iop測定前の待機時間[s] 1bit 1s 換算
    float   wait_ocp;           // 過充電防止時消電測定前の待機時間[s] 1bit 1s換算
    short   low_limit_resistor; // アンテナ抵抗規格 1bit 10Ω
    short   up_limit_resistor;  // アンテナ抵抗規格 1bit 10Ω
    short   low_limit_ocp_v;    // 過充電防止検査の下限規格[V] ver3
    short   up_limit_ocp_v;     // 過充電防止検査の上限規格[V] ver3
    float   wait_voc;           // リセット立上りからVOC測定までの待機時間[s] 1bit 1s 換算 ver3
};


//parameter
struct  cal_info calinfo;
char    reg_num;    /* 選択中の登録CALナンバー */
//function
void erace_calinfo();
void read_regnum();
void read_caliber(cal_info *cal, int num);
void write_caliber_information(cal_info *cal, int num);

/*******************************

    ver1.2.5
    convert code to Ampare

*******************************
float cul_ADC(short code){

    float analog_data;

    analog_data = code * LSB_I / GAIN_I / TIME_INT * CAP  ;

    return( analog_data );

}
*/

/*******************************

 set mode interruptin/degitalin

*******************************/
void set_pullup()
{
    //シーケンサ受信割り込み
    pc.attach(&seq_serialrecive,RawSerial::RxIrq);
    
    /*** ver3 ***/
    sw_start.mode(PullUp);
    
    for (int i = 0; i <= 5; i++){
        seq_in[i].mode(PullUp);
    }
    
}
/*******************************

    Sequence Mode main screen

*******************************/
void seq()
{ 
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte
    char crdata[6];
    
    gu_cls();//clear screen
    gu_fontsize(2);
    gu_print1("Sequenser Mode");
    gu_Button_power_on();//show button

    //seq_start.fall(&trigger);//スタート信号立下りで割込み

    
    //シーケンサのトリガ以外は受け付けない
    while(1) {
        /*** ver3 ***/
        if( sw_start == 0 ) {
        //if ( seq_in[0] == 0 ){
            trigger();
        }

        wait(0.3);

        crdata[0] = 0;
        crdata[1] = 0;
        crdata[2] = 0;

        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if ( crdata[0] == 0x11 && crdata[2] == 1 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。

            //cswnum = crdata[1]; //スイッチ番号
            //cswdata = crdata[2];//ON/OFF情報

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x00;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            if ( crdata[1] == 7 ) {

                gu_Button_power_off();//電源ボタンイメージ反転表示
                wait(0.5);

                led_off();//LED全消灯

                return;//この関数を抜ける

            }   //end if

            /* ver 1.1.1 タッチパネルで測定開始を削除
            else {

                meas_sub();//測定用サブ


            } //else if
            */

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            wait(0.1);

            i2c.read ((addr_gu + 0x01), crdata, 3, true);

        }//if

    }//while(1)
}


/*******************************

    Strart Sequence

*******************************/
void trigger()
{
    char    meas_num;//測定個数
    char    cal_num; //CAL選択ナンバー
    //char    cmd_gu[2];

    gu_cls();//clear screen
    gu_fontsize(2);
    gu_print1("Sequenser Mode");
    gu_fontsize(1);
    gu_cursor(0,3);
    gu_print1("start  ");
    gu_cursor(128,0);
    gu_print1("CAL.");
    

    //シーケンサからCAL選択bit読込と表示
    /*
    cal_num = ( seq_cal_c << 2 ) + ( seq_cal_b << 1 ) +  seq_cal_a;

    cal_num = ( ~ cal_num ) & 0x7 ; //3bit入力の負論理
    */

    /*** v3 debug ***/
    cal_num = 1;

    //read caliber infomation from eeprom
    if( cal_num >= 1 && cal_num <= 6 ) {
        read_caliber(&calinfo, cal_num);
        gu_onebyte( cal_num + 0x30 );//CAL.No.確認用
    } else {
        gu_cls();
        gu_fontsize(1);
        gu_print1("Cal number error");
        wait(1);
    }

    /*** v3 debag ***/
    //meas_num = ( ~(( seq_kosuu_b << 1 ) + seq_kosuu_a )) & 0x3; //2bit負論理
    meas_num = ( ~(( seq_in[2] << 1 ) + seq_in[3] )) & 0x3; //2bit負論理
    /******/

    gu_cursor(128,1);
    gu_print1("n=");
    gu_onebyte( meas_num + 0x30 );//測定個数確認用

    /*** ver3 ***/
    //seq_busy = 1;//DegitalOut busy
    seq_out[4] = 1;

    auto_meas( meas_num );

    //判定結果をシーケンサへ出力
    hantei( meas_num );

    wait(0.1);

    //測定終了ver3
    //seq_busy = 0;//DegitalOut busy
    seq_out[4] = 1;

    //終了表示
    gu_fontsize(1);
    gu_cursor(0,3);
    gu_print1("ready  ");

}

/*******************************************************************************

    EEPROMへCAL情報(struct)を保存
    
        ver3. CAT24M01用に改修 2022.4.12   
            
            1page(256byte)につき1Cal分の品種情報を登録する。
            BYTE_ADDRESS上位9bitでpage指定。下位8bitはpage内アドレス。
       
            argument
                num : CAL登録ナンバー(1~50)
                cal_info : 測定条件

*******************************************************************************/
void write_caliber_information(cal_info *cal, int num)
{
    char   cdata[29];   //1byte*x
    int adrs_init;
    int adrs;

    adrs_init = ((adrs_calinfo[0] << 8 ) & 0xFF00 ) + (adrs_calinfo[1] & 0xFF);

    //EEPROM書込み page指定
    
    adrs = adrs_init + 0x100 * ( num - 1 );
    cdata[0] = ( (adrs & 0xFF00) >> 8 ) & 0xFF;   //address 15~8 bit
    cdata[1] = 0x00;                            //address 7~0 bit

    //連続データ書込み BYTE_ADDRESS 下位8bit 0x00~0x0Bまで
    
    cdata[2] = calinfo.vss_iop & 0xFF;                      //0x00 
    cdata[3] = ( calinfo.vss_iop >> 8 ) & 0xFF;             //0x01 

    cdata[4] = calinfo.vss_ocp & 0xFF;                      //0x02 
    cdata[5] = ( calinfo.vss_ocp >> 8 ) & 0xFF;             //0x03 

    cdata[6] = calinfo.vss_voc & 0xFF;                      //0x04 
    cdata[7] = ( calinfo.vss_voc >> 8 ) & 0xFF;             //0x05

    cdata[8] = calinfo.low_limit_voc & 0xFF;                //0x06
    cdata[9] = ( calinfo.low_limit_voc >> 8 ) & 0xFF;       //0x07

    cdata[10] = calinfo.low_limit_iop & 0xFF;                //0x08
    cdata[11] = ( calinfo.low_limit_iop >> 8 ) & 0xFF;      //0x09

    cdata[12] = calinfo.low_limit_ocp & 0xFF;               //0x0A
    cdata[13] = ( calinfo.low_limit_ocp >> 8 ) & 0xFF;      //0x0B

    cdata[14] = calinfo.up_limit_ocp & 0xFF;                //0x0C
    cdata[15] = ( calinfo.up_limit_ocp >> 8 ) & 0xFF;       //0x0D

    cdata[16] = calinfo.low_limit_ocp_v & 0xFF;             //0x0E
    cdata[17] = ( calinfo.low_limit_ocp_v >> 8 ) & 0xFF;    //0x0F

    cdata[18] = calinfo.up_limit_ocp_v & 0xFF;              //0x10
    cdata[19] = ( calinfo.up_limit_ocp_v >> 8 ) & 0xFF;     //0x11

    cdata[20] = calinfo.wait_iop;                           //0x12
    cdata[21] = calinfo.wait_ocp;                           //0x13
    cdata[22] = calinfo.wait_voc;                           //0x14

    cdata[23] = calinfo.low_limit_resistor / 10;            //0x15 1bitあたり10ohm
    cdata[24] = calinfo.up_limit_resistor / 10;             //0x16 1bitあたり10ohm

    cdata[25] = calinfo.name[0];                            //0x17
    cdata[26] = calinfo.name[1];                            //0x18
    cdata[27] = calinfo.name[2];                            //0x19
    cdata[28] = calinfo.name[3];                            //0x1A

    Soushin = i2c.write (eeprom_adrs, cdata, 29);

    wait(0.2); //ver3

}
/*******************************************************************************

    EEPROMからCAL情報を
    読み出して構造体へ代入する

    argument    num:登録番号

        ver3. CAT24M01用に改修 2022.4.12   
        
*******************************************************************************/
void read_caliber(cal_info *cal, int num)
{
    signed short    sdata[16];      //CAL設定条件
    int i;
    int adrs_init;
    int adrs;
    char cdata[27];
    
    adrs_init = ((adrs_calinfo[0] << 8 ) & 0xFF00) + (adrs_calinfo[1] & 0x00FF);
    
    adrs = adrs_init + 0x100 * ( num - 1 );

    wdata[0] = ( (adrs & 0xFF00) >> 8 ) & 0xFF;   //address 15~8 bit
    wdata[1] = 0x00;                            //address 7~0 bit

    Soushin = i2c.write (eeprom_adrs, wdata, 2,true); //not set stpo at end
    Jyushin = i2c.read ((eeprom_adrs + 0x01), cdata, 1);
    Jyushin = i2c.read ((eeprom_adrs + 0x01), (cdata + 1), 27);//read 27byte 
    
    /*** ver3.0.0 debug***/
    if ( Jyushin != 0 ){
        gu_fontsize(1);
        gu_cursor(0,2);
        gu_print1("not read cal information");   
    } 

    //データ合成 EEPROM_BYTE 0x00~0x11まで2byte結合
    for ( i = 0; i <= 8; i++ ) {
        sdata[i] = cdata[i*2] | ( cdata[ i*2 + 1 ] << 8 );
    }
    
    cal -> number = num;
    cal -> vss_iop = sdata[0];          //0x00
    cal -> vss_ocp = sdata[1];          //0x02
    cal -> vss_voc = sdata[2];          //0x04
    cal -> low_limit_voc = sdata[3];    //0x06
    cal -> low_limit_iop = sdata[4];    //0x08
    cal -> low_limit_ocp = sdata[5];    //0x0A
    cal -> up_limit_ocp = sdata[6];     //0x0C
    cal -> low_limit_ocp_v = sdata[7];  //0x0E
    cal -> up_limit_ocp_v = sdata[8];   //0x10

    cal -> wait_iop = cdata[18];        //0x12 wait_iop
    cal -> wait_ocp = cdata[19];        //0x13 wait_ocp
    cal -> wait_voc = cdata[20];        //0x14 wait_voc
    
    cal -> low_limit_resistor = cdata[21] * 10; //0x15 low_limit_resistor
    cal -> up_limit_resistor = cdata[22] * 10;  //0x16 up_limit_resistor
    
    cal -> name[0] = cdata[23];         //0x17 cal name      
    cal -> name[1] = cdata[24];         //0x18 cal name
    cal -> name[2] = cdata[25];         //0x19 cal name
    cal -> name[3] = cdata[26];         //0x1A cal name

}
/*******************************************************************************

    EEPROMからCAL登録番号を読出し

        ver3. CAT24M01用に改修 2022.4.11
    
*******************************************************************************/
void read_regnum()
{

    //Selective Read Timing
    
    Soushin = i2c.write (eeprom_adrs, adrs_calnum, 2,true);  //ver3
    
    Jyushin = i2c.read ((eeprom_adrs + 0x01), rdata, 1);//read 1byte

    reg_num = rdata[0];
}
/*******************************************************************************

    EEPROMからCAL登録情報全消去("0x00"書込み)
    
        ver3. CAT24M01用に改修 2022.4.11
            0x00000 ~ 0x032FF を消去
    
*******************************************************************************/
void erace_calinfo()
{
    int i;
    int j;

    //init cal number ver3
    reg_num = 0x01;
    wdata[0] = adrs_calnum[0];
    wdata[1] = adrs_calnum[1];
    wdata[2] = reg_num;
    Soushin = i2c.write (eeprom_adrs, wdata, 3);

    wait(0.2);
    
    //write "0x00" by 256 byte

    char wd[258];                       //DATA
    int byte_adrs;                      //送信するBYTE ADDRESS I2C送信データの1,2BYTE目
    const static int cal_adrs = 0x0100; //CAL情報を保存する開始アドレス
    int page = 50;                      //page数
    
    for ( j = 0; j < page; j++){ 

        byte_adrs = cal_adrs + j * 256;
        wd[0] = (byte_adrs & 0xFF00) >> 8;
        wd[1] = byte_adrs & 0xFF;
        for( i = 2; i <= 258; i++) { //write 1page(256byte)
            wd[i] = 0x00;
        }
        Soushin = i2c.write (eeprom_adrs, wd, 258);
    
        wait(0.2);

    }

}
/*******************************************************************************

    ADC(MCP3424) Configuration Register

    ch : Channel Selection Bit
        00 = Select Channel 1
        01 = Select Channel 2
        10 = Select Channel 3
        11 = Select Channel 4

    rate : Sample Rate Selection Bit
        00 = 240 SPS(12bits)
        01 = 60 SPS(14bits)
        10 = 15 SPS(16bits)
        11 = 3.75 SPS(18bits)

*******************************************************************************/
char adc_config(char ch, char rate)
{
    char confreg;   //Configuration Register 1byte

    char rdy = 0;   //Ready Bit
    char cm = 1;    //Conversion Mode Bit
    char gain = 0;  //PGA Gain Selection Bits

    confreg = (( rdy & 0x1 ) << 7 ) + (( ch & 0x3) << 5 ) + (( cm & 0x1 ) << 4) + (( rate  & 0x3 ) << 2) + ( gain & 0x3 ) ;

    return( confreg );
}
/*******************************************************************************

    ADC(MCP3424) Configuration Register
    電流測定チャンネルの選択
    char ch : 1~4ch

*******************************************************************************/
void select_ich(char ch)
{
    char    com;

    switch ( ch ) {
        case 0:
            com =  adc_config( 0, 1 );//ADC3_ch1選択 14bits
            i2c.write( addr_ADC3, &com, 1 );
            break;
        case 1:
            com =  adc_config( 1, 1 );//ADC3_ch2選択 14bits
            i2c.write( addr_ADC3, &com, 1 );
            break;
        case 2:
            com =  adc_config( 0, 1 );//ADC4_ch1選択 14bits
            i2c.write( addr_ADC4, &com, 1 );
            break;
        case 3:
            com =  adc_config( 1, 1 );//ADC4_ch2選択 14bits
            i2c.write( addr_ADC4, &com, 1 );
            break;
    }
}
/*******************************************************************************

    ADC(MCP3424)
    指定addressから2byte読込み

        ver3.0.0 20ms間隔の5回平均

*******************************************************************************/
short read_adc(char addr)//指定addressから2byte読込み
{
    char cdata[2];//1byte
    short sdata;//2byte
    //short kekka;
    //short goukei;
    //int bosu = 5;

    i2c.read( addr + 0x01, cdata, 2);

    /*
    for( int i = 0; i < bosu; i++){
        i2c.read( addr + 0x01, cdata, 2);

        //connect 2byte
        kekka = cdata[0] & 0xFF;
        kekka = ( sdata << 8 ) | cdata[1];

        goukei += kekka;
        
        wait(0.1);

    }
     
    sdata = goukei / bosu;
    */

    i2c.read( addr + 0x01, cdata, 2);

    //connect 2byte
    sdata = cdata[0] & 0xFF;
    sdata = ( sdata << 8 ) | cdata[1];

    return ( sdata );
}
/*******************************************************************************

    AUTO/SEQ Mode

    ワンショットタイマー発生イベント

    For Current measurement
     a recurring interrupt to repeatedly call a function at a specified rate.

*******************************************************************************/
void flip_ch1()
{
    short sdata;

    sdata = read_adc( addr_ADC3 );

    I[0] = sdata * 5 * 0.25;

    //次の測定chへ切替
    select_ich(1);
}

void flip_ch2()
{
    short sdata;

    sdata = read_adc( addr_ADC3 );

    I[1] = sdata * 5 * 0.25;

    //次の測定chへ切替
    select_ich(2);
}

void flip_ch3()
{
    short sdata;

    sdata = read_adc( addr_ADC4 );

    I[2] = sdata * 5 * 0.25;

    //次の測定chへ切替
    select_ich(3);
}

void flip_ch4()
{
    short sdata;

    sdata = read_adc( addr_ADC4 );

    I[3] = sdata * 5 * 0.25;

    //次の測定chへ切替 無し
}

/*******************************************************************************

    Manual Mode

    繰り返しタイマー発生イベント

    For Current measurement
     a recurring interrupt to repeatedly call a function at a specified rate.

*******************************************************************************/
void flip()
{
    short   sdata; //_2byte reading data of ADC
    float   fdata; // ver1.1.4

    switch ( ch_num ) {
        case 0:
        case 1:
            sdata = read_adc( addr_ADC3 );
            break;
        case 2:
        case 3:
            sdata = read_adc( addr_ADC4 );
            break;
    }

    //sdata = sdata * 5 * 0.25;//プリアンプのGAINが1/5なのでここで5倍.ADC14bit分解能で、1bitあたり0.25mv
    /*ver1.1.4*/
    fdata = sdata * 5 * 0.25;//プリアンプのGAINが1/5なのでここで5倍.ADC14bit分解能で、1bitあたり0.25mv

    gu_cursor(0,4);
    gu_print1(" ");
    /*ver1.1.4*/
    gu_putdeci(&fdata);
    //gu_putdeci(&sdata);

    houden[ ch_num ] = 1; //Discharge

    wait(time_discharge); //Discharge time
    
    /*** ver3.0.0 ***/
    
    //電圧測定
    sdata = meas_voltage( ch_num ) * -1 ;
    gu_fontsize(2);
    gu_cursor(108,4);
    gu_putdeck(&sdata);
    gu_print1("V");

    //抵抗測定
    sdata = meas_resistor( ch_num );
    gu_fontsize(2);
    gu_cursor(192,4);
    display_resistor( sdata ); //抵抗値表示サブ
    
    /*****************/

    houden[ ch_num ] = 0; //charging

}
/*********************************
    Manual Mode
    initial screen
*********************************/
void manual_int_hyouji()
{

    /* 画面表示 */
    gu_cls();
    gu_fontsize(2); //change fontsize
    gu_fontWidth(Proportional1);
    gu_print1("Manual Mode");

    gu_cursor(0, 2);
    gu_print1("CH.");
    gu_cursor(40, 14);
    gu_print1("vss");
    gu_cursor(192, 14);
    gu_print1("ch.");
    /*
    gu_cursor(128, 14);
    gu_print1("slct ch.");
    */

    //操作ボタン配置
    gu_Button_power_on();//メニューへ戻る
    gu_button_up(27);//印加電圧増加
    gu_button_down(28);//印加電圧減少
    gu_button_up(32);//ch切替
    //gu_button_down(32);//ch切替

    //Show Reset button(LEFT)
    gu_set_button(25,"R");

}
/*******************************************************************************

    Manual Mode (Main)

*******************************************************************************/
void manual()
{

    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    char cswdata; // 0x00 or 0x01
    char crdata[3];
    char *pcswnum = &cswnum;
    char *pcswdata = &cswdata;
    int i;
    int j;
    float interval;//繰り返し測定間隔(s) <- 積分時間と、繰り返し割込みサブ中のwait(放電時間)も足す
    short vss;
    short sdata;
    int r_flag;
    float ima;
    short ssdata;

    ch_num = 0; //初期電流測定CH.

    interval = time_integral + time_discharge ;//繰り返し割込みの間隔設定
    flipper.attach(&flip, interval);

    read_regnum();//CAL登録No.読込
    read_caliber(&calinfo, reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

    /* 初期表示 */
    manual_int_hyouji();
    //選択測定チャンネルの表示
    gu_fontsize(2); //change fontsize
    gu_cursor(24, 2);
    wdata[0] = ( ch_num + 1 ) + 0x30;
    i2c.write( addr_gu, wdata, 1);

    //初期測定設定
    //set range
    range[0] = 1;//ch.1 10uA測定レンジ
    //select channel
    wdata[0] =  adc_config( 0, 1 );//ADC3_ch1選択 14bits
    i2c.write( addr_ADC3, wdata, 1 );

    /*** 電源印加 ***/
    
    vss = calinfo.vss_iop;

    if ( tenken == true ){
        for ( i = 0; i <= (number_of_channels - 1); i++) {
            dac_out(0,i);
        }
        dac_out( vss,0); //Vss設定 DAC ch.1 ver3.0.0
    } else {
        //apply Vss to all channel
        for ( i = 0; i <= (number_of_channels - 1); i++) {
            dac_out( vss,i); //Vss設定 DAC
        }
    }
    
    /**************/

    gu_cursor(0,8);
    gu_print1("Vss ");

    gu_cursor(64,8);
    sdata = -1 * vss;
    gu_putdeck( &sdata );
    gu_print1("V");

    while(1) {

        crdata[0] = 0;
        crdata[1] = 0;
        crdata[2] = 0;

        //タッチパネルスイッチ読込
        Jyushin = i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if (crdata[0] == 0x11 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            *pcswnum = crdata[1]; //スイッチ番号
            *pcswdata = crdata[2];//ON/OFF情報

            if (cswdata == 0x01) { //タッチしたならば
                switch( cswnum ) { //SWの番号(位置)

                    case 26://SW27 
                        //gu_reverse(0x01);                         //gu_リバース指定
                        //gu_button_up(27);

                        if ( vss < 4500 ) {
                            vss = vss + 100;
                        }

                        if ( tenken == true ){
                            dac_out( vss,ch_num);
                        } else {
                            //apply Vss to all channel
                            for ( i = 0; i <= (number_of_channels - 1); i++) {
                                dac_out( vss,i); //Vss設定 DAC
                            }
                        }

                        gu_reverse(0x00);
                        gu_cursor(64,8);
                        sdata = -1 * vss;
                        gu_putdeck( &sdata );
                        gu_print1("V");

                        //gu_button_up(27);

                        //wait(0.1);

                        break;

                    case 27://SW28
                        //gu_reverse(0x01);                         //gu_リバース指定
                        //gu_button_down(28);//印加電圧減少

                        if ( vss >= 100 ) {
                            vss = vss - 100;
                        }

                        if ( tenken == true ){
                            dac_out( vss,ch_num);
                        } else {
                            //apply Vss to all channel
                            for ( i = 0; i <= (number_of_channels - 1); i++) {
                                dac_out( vss,i); //Vss設定 DAC
                            }
                        }

                        //gu_reverse(0x00);                         //gu_リバース指定
                        gu_cursor(64,8);
                        sdata = -1 * vss;
                        gu_putdeck( &sdata );
                        gu_print1("V");

                        //gu_button_down(28);//印加電圧減少

                        //wait(0.1);

                        break;

                    case 0x07 ://Exit

                        gu_Button_power_off();//電源ボタンイメージ反転表示

                        //割り込み停止
                        flipper.detach();

                        for( i = 0; i <= 3; i++) {
                            houden[i] = 1;//discharge
                        }

                        wait( time_discharge );
                        //set measuring range
                        for( i = 0; i <= 3; i++) {
                            range[i] = 0;//range 1mA
                            houden[i] = 0;//not discharge
                        }

                        /*** ver 3.0.0 ****************************************/
                        for ( i = 0; i <= (number_of_channels - 1); i++) {
                            dac_out(0,i); //Vss設定 DAC
                        }
                        /******************************************************/

                        wait(0.2);

                        for ( i = 0; i <= 15; i++)
                            io[i] = 0; //全てのio"L"

                        return;//この関数を抜ける

                    case 0x18 ://sw25 reset DUT

                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Reset button(Left)
                        gu_set_button(25,"R");

                        wait(0.1);

                        gu_reverse(0x00); //gu_リバース解除
                        gu_set_button(25,"R"); //Show Reset button(Left)

                        io_reset[ch_num] = 1;//ver3.0.0 R="H"

                        //set measuring range  ver1.1.0
                        for( i = 0; i <= 3; i++)
                            range[i] = 0;//range 1mA

                        r_flag = 1;

                        //割り込み停止 電流測定用タイマー停止
                        flipper.detach();

                        break;

                    case 31 ://sw32 CH選択

                        //gu_reverse(0x01);//gu_リバース指定
                        //gu_button_up(32);
                        //gu_reverse(0x00);//gu_リバース解除

                        if ( ch_num < ( number_of_channels - 1 )) {
                            ch_num = ch_num + 1;
                        } else {
                            ch_num = 0;
                        } //ver1.1.0
                        
                        select_ich(ch_num);//ADC測定CHの変更

                        //set measuring range
                        for( i = 0; i <= 3; i++)
                            range[i] = 0; //range 1mA

                        range[ch_num] = 1; //range 10uA

                        if ( tenken == true ){
                            for ( i = 0; i <= (number_of_channels - 1); i++) {
                                dac_out(0,i); //Vss設定 DAC
                            }
                            dac_out( vss,ch_num);
                        } else {
                            //apply Vss to all channel
                            for ( i = 0; i <= (number_of_channels - 1); i++) {
                                dac_out( vss,i); //Vss設定 DAC
                            }
                        }

                        //選択測定チャンネルの表示
                        gu_cursor(24, 2);
                        wdata[0] = ( ch_num + 1 ) + 0x30;
                        i2c.write( addr_gu, wdata, 1);

                        //gu_button_up(32);

                        wait(0.1);

                        break;

                } //switch
                Jyushin = i2c.read ((addr_gu + 0x01), crdata, 3, true);

            }//if
        }//if

        //ver1.1.0 0.1s*10(jの値)=1s待機後(プラスリレー制御時間)に電流測定用タイマー始動 
        if ( j >= 10 ) {
            io_reset[ch_num] = 0; // R = "OPEN"
            range[ ch_num ] = 1; //range 10uA
            r_flag = 0;
            j = 0;
            flipper.attach(&flip, interval);//割込み開始
        }

        if ( r_flag == 1 ) {
            j = j + 1;

            //R=Hの時の電流測定(1ma renge)
            select_ich( ch_num );
            ssdata = read_adc( addr_ADC3 );
            ima = ssdata * 5 * 0.25;

            gu_cursor(0,4);
            gu_fontsize(2);
            gu_print1(" ");
            gu_putdeci_mA(&ima);
        }

        /*
        //電圧測定
        sdata = meas_voltage( ch_num ) * -1 ;
        gu_fontsize(2);
        gu_cursor(108,4);
        gu_putdeck(&sdata);
        gu_print1("V");

        //抵抗測定
        sdata = meas_resistor( ch_num );
        gu_fontsize(2);
        gu_cursor(192,4);
        display_resistor( sdata ); //抵抗値表示サブ
        */

        wait( 0.1 );

    }//While
}

/*****************************

    I2C General Call

*****************************/
void general_call(char com)
{
    char    cmd[1];

    cmd[0]= com;
    i2c.write(0x00, cmd, 1); //General Call
}
/*******************************************************************************

    MAIN

*******************************************************************************/
int main(void)
{
    while(1) {

        wait(0.2);

        //ver3.0.0
        //uart.format(7, Serial::Even, 1);

        set_pullup();

        general_call(0x06); //ADC power on reset

        dac_init(); //DAC 初期化

        gu_initial();//初期画面へ
        //utility();
    }
}   //main end

void gu_initial()
{
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte0
    //char *pcmd = cmd_gu;
    char clumi; //輝度設定用変数 01h<=n<=08h
    char* pclumi = &clumi; //ポインタの定義
    char crdata[3];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    char cswdata; // 0x00 or 0x01
    char *pcswnum = &cswnum;
    char *pcswdata = &cswdata;
    char csyoudo[4];
    int i;
    float duty_pwm;

    for ( i = 0; i <= ( number_of_channels - 1 ); i++) {
        leds[i].period_us(period_pwm); //Set tha PWM period(us)
    }

    duty_pwm = 0; //表示器立ち上がるまでLEDOFF

    for( i = 0; i <= 3; i++) {
        leds[i].write(duty_pwm);//Set Duty
    }

    i2c.frequency(100000); //gu_D I2Cクロックレート(HZ) 400khz以下

    cmd_gu[0]= 0x1B;
    cmd_gu[1]= 0x40;
    i2c.write(addr_gu, cmd_gu, 2); //gu-D ESC 初期化
    wait(0.2);

    //メモリ00h番地(GU_D輝度設定データ)読み出し
    //wdata[0] = 0x00;
    wdata[0] = adrs_kido[0];
    wdata[1] = adrs_kido[1];
    Soushin = i2c.write (eeprom_adrs, wdata, 2,true);    //読込先頭アドレス指定 ReStart
    Jyushin = i2c.read ((eeprom_adrs + 0x01), rdata, 1);//read 1byte
    *pclumi = rdata[0];
    //輝度設定更新
    if(*pclumi==0x00 || *pclumi > 0x08) *pclumi=0x05;
    gu_luminance(pclumi);

    gu_fontsize(2); //change fontsize
    //ver1.2.3
    //gu_print1("ILF Iop/Voc/O.C.P/R");
    gu_print1("ILF mode selectiion");
    //upto
    //gu_CRLF();//CR+LF
    //gu_print1("Settings");
    gu_fontsize(1);
    gu_cursor(192,1);
    gu_print1("ver");
    gu_onebyte( version_major + 0x30 );
    gu_print1(".");
    gu_onebyte( version_minor + 0x30 );
    gu_print1(".");
    gu_onebyte( version_build + 0x30 );

    gu_touchPara(0,touch);//タッチ感度 00h~07h

    //MODE選択用ボタンの表示
    gu_set_button(9,"");
    gu_set_button(17,"");
    gu_set_button(25,"");
    gu_set_button(13,"");
    gu_set_button(21,"");
    gu_set_button(29,"");
    //LED Brighness
    gu_fontsize(2);
    gu_cursor(36,32/8);
    gu_print1("CAL");
    gu_cursor(36,64/8);
    gu_print1("LUX");
    //gu_cursor(36,80/8);
    //gu_print1("illumi");
    //Display Brightness
    gu_cursor(36,96/8);
    gu_print1("Utility");
    //Auto MODE
    gu_cursor(164,32/8);
    gu_print1("Auto");
    //Manual Mode
    gu_cursor(164,64/8);
    gu_print1("Manual");
    //Sequenser Mode
    gu_cursor(164,96/8);
    gu_print1("SEQ");

    /**********************
     SDカードファイルオープン
    **********************/

    mkdir("/sd/mydir", 0777);

    FILE *fp = fopen("/sd/mydir/iop.csv", "ab+");//ディレクトリとファイル名の指定

    if(fp == NULL) {
        /*ver1.1.3
        gu_fontsize(1);
        gu_cursor(0,2);
        gu_print1("Could not open file for SD card");
        */
    } else {
        fprintf(fp, "NewData  R IOP OCP VOC");
        fprintf(fp, "\n");
        fclose(fp);
    }
    /**********************
        LED照度初期設定
    **********************/
    read_syoudo( csyoudo );

    //gu-D タッチスイッチ読み出し動作設定 p49
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49
 
    while(1) {
        
        //タッチスイッチ読み出し
        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if (crdata[0] == 0x11 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            *pcswnum = crdata[1]; //スイッチ番号
            *pcswdata = crdata[2];//ON/OFF情報
            
            if (cswdata == 0x01) { //タッチしたならば
                switch( cswnum ) { //SWの番号(位置)

                    case 0x08 ://SW9 CAL登録画面
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(9,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        select_cal();//CAL選択画面へ移動

                        return;

                    case 0x10 ://SW17
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(17,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        adjust_illumination();//LED照度調整へ移動

                        return;

                    case 0x18 ://SW25
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(25,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        utility();//画面輝度調整へ移動

                        return;

                    case 0x0C ://SW13 自動測定モード
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(13,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        auto_run();

                        return;

                    case 0x14 ://SW21 手動測定モード
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(21,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        manual();

                        return;

                    case 0x1C ://SW29 シーケンサ制御モード
                        //gu_リバース指定
                        gu_reverse(0x01);
                        //Show Button
                        gu_set_button(29,"");
                        wait(0.1);
                        //gu_リバース解除
                        gu_reverse(0x00);

                        seq();

                        return;

                } //switch

            }//if(cswdata == 0x01) {
        } //if(crdata[0] == 0x11 ) {

        wait(0.1);//タッチスイッチ入力読み出し間隔

    } //while(1) {

}

/*******************************************************************************

    CAL選択画面 sub
    
        ver3.0.0    CAL名を追加

*******************************************************************************/
void show_info(int n)
{
    short sdata[6];
    char cl[2];

    read_caliber(&calinfo,n);

    //読出したCAL情報の表示
    gu_fontsize(1);
    gu_cursor(0,2);
    gu_print1("                ");
    gu_fontsize(1);
    gu_cursor(0,2);
    gu_print1("No.");
    
    cl[1] = calinfo.number % 10 + '0';
    cl[0] = calinfo.number /10 + '0';
    
    gu_print(cl);
    //gu_putdec(&calinfo.number);

    gu_print1(" CAL.");
    //gu_print1(calinfo.name);
    i2c.write(addr_gu, calinfo.name, 4); //4byte ascii code

    gu_cursor(0,3);
    gu_print1("Vss(Iop) =");
    sdata[0] = -1 * calinfo.vss_iop;
    gu_putdeck(&sdata[0]);
    gu_print1("V ");
    gu_cursor(0,4);
    gu_print1("Vss(ocp) =");
    sdata[1] = -1 * calinfo.vss_ocp;
    gu_putdeck(&sdata[1]);
    gu_print1("V ");
    gu_cursor(0,5);
    gu_print1("Vss(Voc) =");
    sdata[2] = -1 * calinfo.vss_voc;
    gu_putdeck(&sdata[2]);
    gu_print1("V ");
}
/*******************************************************************************

    GU-D CAL選択スイッチボタン再表示 サブ

        画面上にあるスイッチの配置
        
        01,02,03,04,05,06,07,08,
        09,10,11,12,13,14,15,16,
        17,18,19,20,21,22,23,24,
        25,26,27,28,29,30,31,32,
    
*******************************************************************************/
void redraw_sw(int dig, char sw_num){
    
    char str_num[3];    // ascii code
    char sw;            // GU-D Swich Number
    
    str_num[2] = 0;     // null終端
    
    if (  dig >= 1 ){
        str_num[0] = dig + 0x30;   //convert ASCII 10の位
    } else {
        str_num[0] = 0x20;         //space
    }

    for ( sw = 17; sw <= 29; sw++ ){ 
        
        if ( sw >= 22 && sw <= 24 ){
            continue;
        }
        
        if ( sw <= 21 ){
            str_num[1] = ( sw - 16 ) + 0x30;
        } else if ( sw >= 24 && sw <= 28 ){    
            str_num[1] = ( sw - 19 ) + 0x30;       
        } else if ( sw == 29) {
            str_num[0] = ( dig + 1 )+ 0x30;
            str_num[1] = 0x30;
        }
        
        if ( sw_num != sw ){
            gu_set_button(sw,str_num);
        } else {
            gu_reverse(0x01);   //gu_リバース指定
            gu_set_button(sw,str_num);
            gu_reverse(0x00);   //gu_リバース解除
        }
    }//for
}

/*******************************************************************************

    CAL選択画面 #CAL登録画面
    
        画面上にあるスイッチの配置
        
        01,02,03,04,05,06,07,08,
        09,10,11,12,13,14,15,16,
        17,18,19,20,21,22,23,24,
        25,26,27,28,29,30,31,32,

*******************************************************************************/
void select_cal()
{
    char crdata[3];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    char cswdata; // 0x00 or 0x01
    char *pcswnum = &cswnum;
    char *pcswdata = &cswdata;
    char calnum;    //選択したCALナンバー
    
    int digit = 0 ;     //CAL番号 10の位の値 0~4
    bool redraw ;       //再描画

    read_regnum();//EEPROMに保存した選択CAL_NO.の読み出し

    while(1){//ver3

        redraw = false;
    
        calnum = 0;         //initial
    
        gu_cls();           //GU-D 画面クリア
    
        show_info(reg_num);
    
        gu_fontsize(2); //change fontsize
        gu_cursor(0,0);
        //ver3.0.0
        //gu_print1("Select CAL.");
        gu_print1("CONFIG");
        
        //Set Button init ver3.0.0
        redraw_sw(calnum,0);
    
        gu_set_button_font1(7,"slct");
        gu_set_button_font1(8,"set");
        
        gu_button_up(24);
        gu_button_down(32);
    
        while(1) {
            //タッチスイッチ読み出し
            i2c.read ((addr_gu + 0x01), crdata, 3, true);
    
            if (crdata[0] == 0x11 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
                *pcswnum = crdata[1]; //スイッチ番号
                *pcswdata = crdata[2];//ON/OFF情報
    
                if (cswdata == 0x01) { //タッチしたならば
                    switch( cswnum ) { //SWの番号(位置)
                    
                        case 23:  //SW24 page up
                            
                            if ( digit <= 3 ){
                                digit += 1;
                            } else if ( digit == 4 ){
                                digit = 0;
                            }
                            
                            redraw_sw(digit,0);
                            
                            //calnum = digit * 10 + 1;
                            //show_info(calnum);
                            
                            break;
                            
                        case 31: //SW32 page down
    
                            if ( digit >= 1 ){
                                digit -= 1;
                            } else if ( digit == 0 ) {
                                digit = 4;
                            }
    
                            redraw_sw(digit,0);
    
                            //calnum = digit * 10 + 1;                                          
                            //show_info(calnum);
                                  
                            break;
    
                        case 16:  //SW17
                        case 17:  //SW18
                        case 18:  //SW19
                        case 19:  //SW20
                        case 20:  //SW21
    
                            calnum = cswnum - 15 + (digit*10);
    
                            redraw_sw(digit,cswnum + 1);
    
                            show_info(calnum);
    
                            break;
    
                        case 24:  //SW25
                        case 25:  //SW26
                        case 26:
                        case 27:
    
    
                            calnum = cswnum - 18 + (digit*10);
    
                            redraw_sw(digit,cswnum + 1);
    
                            show_info(calnum);
    
                            break;
    
                        case 28:    //SW29
    
                            calnum = ((digit + 1 )*10);
    
                            redraw_sw(digit,cswnum + 1);
    
                            show_info(calnum);
    
                            break;
    
                        case 0x06:  //SW7 ”slct"(CAL選択)ボタン
    
                            if ( calnum >= 1 && calnum <=6 ) {
                                reg_num = calnum;
    
                                //ver3 EEPROM書込み Byte Write
                                wdata[0] = adrs_calnum[0]; //byte address a15~8
                                wdata[1] = adrs_calnum[1]; //byte address a7~a0
                                wdata[2] = reg_num;
                                Soushin = i2c.write (eeprom_adrs, wdata, 3); //send stop at end default value is false.
    
                                //GU-D
                                gu_reverse(0x01);   //gu_リバース指定
                                gu_set_button_font1(7,"slct");
                                wait(0.2);
                                gu_reverse(0x00);   //gu_リバース解除
    
                                read_caliber(&calinfo,reg_num);
                                
                                return;
    
                            } else if( calnum == 0 ) {
                                //CALNo.選択しなければ、何もしないでこのサブを抜ける
                                gu_reverse(0x01);   //gu_リバース指定
                                gu_set_button_font1(7,"slct");
                                wait(0.2);
                                gu_reverse(0x00);   //gu_リバース解除
                                return;
                            }
    
                            break;
    
                        case 0x07:  //SW8 "set"ボタン
    
                            if ( calnum >= 1 && calnum <= 50 ) {
                                gu_reverse(0x01);   //gu_リバース指定
                                gu_set_button_font1(8,"set");
                                wait(0.2);
                                gu_reverse(0x00);   //gu_リバース解除
    
                                setup_cal_information(calnum);//CAL情報登録画面へ
                                
                                //return;
                                redraw = true;
                            }
                            break;
    
                    } //switch
                    
                    if (redraw){
                        break;  //exit while
                    }
    
                }//if(cswdata == 0x01) {
            } //if(crdata[0] == 0x11 ) {
            wait(0.1);//タッチスイッチ入力読み出し間隔
        } //while(1)
        
    }
}

/*******************************************************************************

    CAL情報登録画面 サブルーチン
        項目の表示
    
        ver3.0.0    22.4.12
    
        x=0  : vss_iop[V]
        x=1  : vss_ocp[V]
        x=2  : vss_voc[V]
        x=3  : low_limit_voc[V]
        x=4  : low_limit_iop[uA]
        x=5  : low_limit_ocp[uA]
        x=6  : up_limit_ocp[uA]
        x=7  : low_limit_ocp_v[V]
        x=8  : up_limit_ocp_v[V]
        x=9  : wait_iop[s]
        x=10 : wait_ocp[s]
        x=11 : wait_voc[s]
        x=12 : low_limit_resistor[Ω]
        x=13 : up_limit_resistor[Ω]
        x=14 : cal_name(ASCII)
        
        /1.2.1
        x=0 : vss_iop[V]
        x=1 : vss_ocp[V]
        x=2 : vss_voc[V]
        x=3 : low_limit_voc[V]
        x=4 : low_limit_iop[uA]
        x=5 : low_limit_ocp[uA]
        x=6 : up_limit_ocp[uA] ver1.2.2 追加 
        x=7 : wait_iop[s]
        x=8 : wait_ocp[s]
        x=9 : low_limit_resistor[Ω]
        x=10 : up_limit_resistor[Ω]
        /

*******************************************************************************/
void hyouji_cal_param(int x)
{
    gu_fontsize(2);
    gu_cursor(0,4);
    gu_print1("                                ");
    gu_cursor(0,6);
    gu_print1("                                ");

    gu_fontsize(2);    
    gu_cursor(zahyou_para1[0],zahyou_para1[1]);
    gu_print1(cpara1[x]);
    gu_fontsize(2);
    gu_cursor(zahyou_para2[0],zahyou_para2[1]);    
    gu_print1(cpara2[x]);
    
    gu_fontsize(2);
    gu_cursor(zahyou_unit[0],zahyou_unit[1]);
    
    if ( x == 12 || x == 13 ){
        wdata[0] = 0xEA; //Ω
        i2c.write( addr_gu, wdata, 1);
    } else {
        gu_print1(cunit[x]);
    }

}

/*******************************************************************************

    CAL情報登録画面 sub
    
    para    kind of parameter
    idata   data value
    inc     add number  ex)0x64 0x0A 0x01

*******************************************************************************/
/*** 加算 ***/
void increase_param(int para, signed short *sdata, short inc)
{
    switch ( para ) { //パラメータの項目によって上限値異なる
        case 0://vss_iop
        case 1://vss_ocp
        case 2://vss_voc
        case 3://low_limit_voc
        case 7://low_limit_ocp_v
        case 8://up_limit_ocp_v
            if(*sdata <= ( 4999 - inc )) {
                *sdata = *sdata + inc ;
            }
            break;//switch ( param ){

        case 4: //low_limit_iop
        case 5: //low_limit_o.c.p
        case 6: //up_limit_o.c.p
            if(*sdata <= ( 2500 - inc / 10 )) {
                *sdata = *sdata + inc /10 ;
            }
            break;//switch ( param )
        case 9:     //wait_iop
        case 10:    //wait_ocp
        case 11:    //wait_voc

            if(*sdata <= ( 2550 - inc / 10 )) {
                *sdata = *sdata + inc / 10 ;
            }
            break;//switch ( param )

        case 12: //low_limit_resistor
        case 13: //up_limit_resistor
            if(*sdata <= ( 2550 - inc )) {
                *sdata = *sdata + inc;
            }
            break;
        
    }//switch ( param ){
}

/*** 減算 ***/
void decrease_param(int para, signed short *sdata, short dec)
{
    switch ( para ) { //パラメータの項目によって上限値異なる
        case 0://vss_iop
        case 1://vss_ocp
        case 2://vss_voc
        case 3://low_limit_voc
        case 7://low_limit_ocp_v
        case 8://up_limit_ocp_v

            if(*sdata >= dec ) {
                *sdata = *sdata - dec;
            }
            break;

        case 4://low_limit_iop

            if(*sdata >= dec / 10 ) {
                *sdata = *sdata - dec / 10;
            }
            break;

        case 5://low_limit_o.c.p
        case 6://up_limit_o.c.p        

            if(*sdata >= -2500 + dec / 10 ) {
                *sdata = *sdata - dec / 10;
            }
            break;

        case 9:     //wait_iop
        case 10:    //wait_ocp
        case 11:    //wait_voc

            if(*sdata >= dec / 10 ) {
                *sdata = *sdata - dec / 10 ;
            }
            break;//switch ( param )

        case 12:    //low_limit_resistor
        case 13:    //up_limit_resistor
        
            if(*sdata >= dec ) {
                *sdata = *sdata - dec;
            }
            break;

    }//switch ( param ){
}

/*******************************************************************************

    CAL NAME (ASCII)
        3文字で構成(ex.B61)。1文字づつ上下キーで変更する。
        範囲はASCII表において 0x30~0x5A
        
        ver3.0.0 2022.4.13

*******************************************************************************/
/*** UP ***/
void up_ascii(char *c){

    if (*c >= 0x5A ){
        *c = 0x30;
    } else if ( *c < 0x30 ){
        *c = 0x30;
    } else {
        *c = *c + 1;
    }       

}
/*** DOWN ***/
void down_ascii(char *c){

    if (*c > 0x5A ){
        *c = 0x5A;
    } else if ( *c <= 0x30 ){
        *c = 0x5A;
    } else {
        *c = *c - 1;
    }       

}
/*******************************************************************************
    
    CAL情報登録画面 表示

    ****** Swich matrix ******
    01,02,03,04,05,06,07,08,
    09,10,11,12,13,14,15,16,
    17,18,19,20,21,22,23,24,
    25,26,27,28,29,30,31,32,
    ***************************

*******************************************************************************/
void disp_setup_cal(char cal_num , int parameter){

    char wdata[2];

    gu_cls();//clear dispray
    gu_fontsize(1);
    gu_print1("SETUP No.");
    wdata[0] = ( cal_num / 10 ) + 0x30;//ver3.0.0
    wdata[1] = ( cal_num % 10 ) + 0x30;//show caliber number
    i2c.write(addr_gu, wdata, 2);    
        
    if( parameter == 14 ){
        gu_button_up(sw_up_set[3]);       
        gu_button_down(sw_down_set[3]);    
    }
    
    gu_set_button_font1(7,"esc");
    gu_set_button_font1(8,"save");
    gu_button_up(17);
    gu_button_down(25);
    gu_button_up(sw_up_set[0]);
    gu_button_up(sw_up_set[1]);
    gu_button_up(sw_up_set[2]);
    gu_button_down(sw_down_set[0]);
    gu_button_down(sw_down_set[1]);
    gu_button_down(sw_down_set[2]);
    
    hyouji_cal_param(parameter);

}


/*******************************************************************************

    PASS WORD 画面

*******************************************************************************/
void pw(int* pflag){

    char crdata[3];//GUDからの受信データ
    char strnum[2];
    char basho = 0;
    char word[YOSO];
    char c[2];//GU-D SW 表示文字
    int j = 0;
    
    gu_cls();//clear dispray
    
    strnum[1] = 0;//NULL
    c[1]=0;//NULL

    for ( int i = 0; i <=25; i++ ){
        strnum[0] = i + 0x41;
        gu_set_button( (basho + 1 ) ,strnum);
        basho = basho + 1;
    }
    
    wait(0.2);
    
    int i = 0;

    while(1) {
        
        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if (crdata[0] == 0x11 && crdata[2] == 0x01 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。&& タッチしたならば
            
            word[j] = crdata[1] + 0x41; 
            c[0] = word[j];
            
            gu_reverse(1);
            gu_set_button( (crdata[1] + 1 ) ,c);
            gu_reverse(0);

            j = j + 1; 
        
        }
        
        if ( j == YOSO ){
            
            while (1){
                if ( word[i] != pass[i] ){
                    *pflag = 1;
                    break;
                }
                if (i == ( YOSO - 1) ){
                    break;
                }
                
                i += 1;
            }
            
            wait(0.5);
            return;

        }//if
        
        wait(0.2);

    }//while 
}
/*******************************************************************************

    CAL情報登録画面   MAIN
    別途システム設計図,EEPROMのシートを参照
    
    ver3.0.0
    
    param:
        0:vss_iop
        1:vss_ocp
        2:vss_voc
        3:low_limit_voc
        4:low_limit_iop
        5:low_limit_ocp
        6:up_limit_ocp
        7:low_limit_ocp_v
        8:up_limit_ocp_v
        9:wait_iop
        10:wait_ocp
        11:wait_voc
        12:LowLimitResistor
        13:UPLimitResistor
        14:CAL_name

*******************************************************************************/
void setup_cal_information(char cal_num)
{
    int             param;              //設定するパラメータの選択
    char            crdata[3];          //GU-Dからの受信DATA 3byte
    signed short    sdata_cal[18];      //CAL設定条件
    signed short    hyouji_data;
    int             param_sum = 14;     //パラメータの最大設定数
    char            c_temp[4];          //CAL名設定条件 calinfo.name
    //int i;
    //short           sdata_byte[16];     //EEPROM BYTEごとのDATA 1byte
    //char          cmd_gu[32];         //gu-DへのI2Cコマンド用配列 1byte0
    //char            adrs_cal;           //EEPROM CAL情報を保存しているアドレス 0x90~
    
    int pwflag = 0;

    pw(&pwflag);
    
    if ( pwflag != 0 ){
        return;
    }
    
    //Load caliber information
    read_caliber(&calinfo,cal_num);

    sdata_cal[0] = calinfo.vss_iop;
    sdata_cal[1] = calinfo.vss_ocp;
    sdata_cal[2] = calinfo.vss_voc;
    sdata_cal[3] = calinfo.low_limit_voc;
    sdata_cal[4] = calinfo.low_limit_iop;
    sdata_cal[5] = calinfo.low_limit_ocp;
    sdata_cal[6] = calinfo.up_limit_ocp;
    sdata_cal[7] = calinfo.low_limit_ocp_v;
    sdata_cal[8] = calinfo.up_limit_ocp_v;
    sdata_cal[9] = calinfo.wait_iop;
    sdata_cal[10] = calinfo.wait_ocp;
    sdata_cal[11] = calinfo.wait_voc;
    sdata_cal[12] = calinfo.low_limit_resistor;
    sdata_cal[13] = calinfo.up_limit_resistor;

    c_temp[0] = calinfo.name[0];
    c_temp[1] = calinfo.name[1];
    c_temp[2] = calinfo.name[2];
    c_temp[3] = calinfo.name[3];

    //初期表示はCAL名設定
    param = 14;
    disp_setup_cal(cal_num,param);    

    while(1) {
        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if (crdata[0] == 0x11 && crdata[2] == 0x01 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。&& タッチしたならば
            //cswnum = crdata[1]; //スイッチ番号
            //cswdata = crdata[2];//ON/OFF情報

            //タッチしたSWの番号(位置)による分岐
            
            //sw17 パラメータ変更スイッチ(上)
            if ( crdata[1] == 16 ){
    
                if ( param <= param_sum -1 ) {
                    param = param + 1;
                } else {
                    param = 0;
                }
    
                disp_setup_cal(cal_num,param);    
                //hyouji_cal_param(param);//設定パラメータ表示
                
            }
            
            //case 0x18 ://sw25 パラメータ変更スイッチ(下)
            if ( crdata[1] == 24 ){
    
                if ( param >= 1 ) {
                    param = param - 1;
                } else {
                    param = param_sum;
                }
    
                disp_setup_cal(cal_num,param);    
                //hyouji_cal_param(param);//設定パラメータ表示
                
            }
    
            if ( crdata[1] == (sw_up_set[0] - 1)){ //increase
    
                // if set caliber name .. ver3
                if ( param == 14 ){ 
                    up_ascii(&c_temp[0]);
                } else {    
                    increase_param(param, &sdata_cal[param], 1000);
                }
            }
    
            if ( crdata[1] == (sw_up_set[1] - 1)){ //increase
    
                if ( param == 14 ){ 
                    up_ascii(&c_temp[1]);
                } else {
                    increase_param(param, &sdata_cal[param], 100);
                }
             }
    
            if ( crdata[1] == (sw_up_set[2] - 1)){ //SW** increase
    
                if ( param == 14 ){ 
                    up_ascii(&c_temp[2]);
                } else {
                    increase_param(param, &sdata_cal[param], 10);
                }
            }
    
            if ( crdata[1] == (sw_up_set[3] - 1)){ //SW** increase CAL名設定時に使用する
    
                if ( param == 14 ){ 
                    up_ascii(&c_temp[3]);
                }
            }
    
            if ( crdata[1] == (sw_down_set[0] - 1)){ //SW** decrease
    
                if ( param == 14 ){ 
                    down_ascii(&c_temp[0]);
                } else {    
                    decrease_param(param, &sdata_cal[param], 1000);
                }
            }
    
            if ( crdata[1] == (sw_down_set[1] - 1)){ //SW** decrease
    
                if ( param == 14 ){ 
                    down_ascii(&c_temp[1]);
                } else {
                    decrease_param(param, &sdata_cal[param], 100);
                }
            }
    
            if ( crdata[1] == (sw_down_set[2] - 1)){ //SW** decrease
    
                if ( param == 14 ){ 
                    down_ascii(&c_temp[2]);
                } else {
                    decrease_param(param, &sdata_cal[param], 10);
                }
            }
    
            if ( crdata[1] == (sw_down_set[3] - 1)){ //SW** decrease
    
                if ( param == 14 ){ 
                    down_ascii(&c_temp[3]);
                } 
            }
                
            if ( crdata[1] == 6 ){   //SW7 "esc"ボタン
    
                gu_reverse(1);
                gu_set_button_font1(7,"esc");
                wait(0.2);
                gu_reverse(0);//ver3                    
    
                return; //何もせずに抜ける
            }
            
            if ( crdata[1] == 7 ){   //SW8 "save"保存ボタン
            
                //ver3 CAL情報 代入
                //*** ver3 ***
                calinfo.vss_iop = sdata_cal[0];
                calinfo.vss_ocp = sdata_cal[1];
                calinfo.vss_voc = sdata_cal[2];
                calinfo.low_limit_voc = sdata_cal[3];
                calinfo.low_limit_iop = sdata_cal[4];
                calinfo.low_limit_ocp = sdata_cal[5];
                calinfo.up_limit_ocp = sdata_cal[6];
                calinfo.up_limit_ocp_v = sdata_cal[7]; 
                calinfo.low_limit_ocp_v = sdata_cal[8];
                calinfo.wait_iop = sdata_cal[9];
                calinfo.wait_ocp = sdata_cal[10];
                calinfo.wait_voc = sdata_cal[11];
                calinfo.low_limit_resistor = sdata_cal[12];
                calinfo.up_limit_resistor = sdata_cal[13];
                
                calinfo.name[0] = c_temp[0];
                calinfo.name[1] = c_temp[1];
                calinfo.name[2] = c_temp[2];
                calinfo.name[3] = c_temp[3];
    
                /*ver3 Byte Write CALNO.EEPROM 書込み 
                reg_num = cal_num;
                wdata[0] = adrs_calnum[0];
                wdata[1] = adrs_calnum[1];
                wdata[2] = reg_num;
                
                Soushin = i2c.write (eeprom_adrs, wdata, 3); //send stop at end
                wait(0.2);
                */
    
                /*** ver3 ***
                //CAL情報 >> EEPROM
                //送信完了ならば実行
                if(Soushin == 0) {
    
                    write_caliber_information(&calinfo, cal_num);
    
                    //ver1.2.3
                } else {
                    gu_fontsize(1);
                    gu_cursor(0,2);
                    gu_print1("can not save cal no");
                    wait(2);
                    return;
                }
                ***/
                
                /*** ver3 ***/
                write_caliber_information(&calinfo, cal_num);                    
    
                //送信完了ならば実行
                if(Soushin == 0) {
                    gu_reverse(1);
                    gu_set_button_font1(8,"save");
                    wait(0.2);
                    gu_reverse(0);//ver3
                    return;//CAL情報登録画面を抜ける
    
                    //ver1.2.3
                } else {
                    gu_fontsize(1);
                    gu_cursor(0,2);
                    gu_print1("can not save cal information");
                    wait(2);
                    return;
                }
            
            }//end if
        }//end if
        
        //gu-D表示 ver3
        gu_fontsize(2);
        gu_cursor(zahyou_val[0],zahyou_val[1]);   //表示位置の指定

        switch ( param ) {
            case 0://vss_iop
            case 1://vss_ocp
            case 2://vss_voc
            case 3://low_limit_voc
            case 7://low_limit_voc_v
            case 8://up_limit_voc_v
                hyouji_data = sdata_cal[param] * -1;
                gu_putdeck ( &hyouji_data );
                break;
                
            case 4://low_limit_iop
            case 5://low_limit_ocp
            case 6://up_limit_ocp
                hyouji_data = sdata_cal[param] * 10;
                gu_putdeck ( &hyouji_data );
                break;
                
            case 9:  //wait_iop
            case 10: //wait_ocp
            case 11: //wait_voc
                //ver1.1.0
                hyouji_data = sdata_cal[param];
                gu_putdec ( &hyouji_data );
                break;
                
            case 12://low_limit_resistor
            case 13://up_limit_resistor
                hyouji_data = sdata_cal[param];
                gu_putdec ( &hyouji_data );
                break;
                
            case 14: //cal name ver3
                i2c.write(addr_gu, c_temp, 4); //3byte ascii code
                break;

        }//swith
        wait(0.1);//gu-D 読込間隔の設定
    }//while
}

/*********************************

    Auto Mode (sub)
    自動測定モード 初期画面

*********************************/
void auto_int_hyouji()
{
    //short st;
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte

    gu_cls();
    gu_fontsize(1);
    gu_print1("AUTO MODE CAL No.");
    cmd_gu[0] = reg_num + 0x30;
    i2c.write(addr_gu, cmd_gu, 1);
    gu_Button_power_on();//show button

}
/*******************************************************

    Auto Mode (Main)
    自動測定モード 画面
    ver1.04 パネルタッチ -> スタートスイッチで測定開始へ変更

*******************************************************/
void auto_run()
{
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte
    char crdata[6];
    //char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    //int     i;
    //float   fdata[4][4];//ファイル出力用
    //short   sdata[4];
    //short   s;

    read_regnum();//CAL登録No.読込
    read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

    auto_int_hyouji();

    //dac_init(); //DAC 初期化

    //gu-D タッチスイッチ読み出し動作設定 p49
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

    wait(0.1);

    Jyushin = i2c.read ((addr_gu + 0x01), crdata, 3, true);

    while(1) {
        //スタートスイッチで測定開始
        if ( sw_start == 0 ) {
            meas_sub();
        }

        wait(0.1);

        crdata[0] = 0;
        crdata[1] = 0;
        crdata[2] = 0;

        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if ( crdata[0] == 0x11 && crdata[2] == 1 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。

            //cswnum = crdata[1]; //スイッチ番号
            //cswdata = crdata[2];//ON/OFF情報

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x00;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            if ( crdata[1] == 7 ) {

                gu_Button_power_off();//電源ボタンイメージ反転表示
                wait(0.5);

                led_off();//LED全消灯

                return;//この関数を抜ける

            }   //end if

            /* ver 1.1.1 タッチパネルで測定開始を削除
            else {

                meas_sub();//測定用サブ


            } //else if
            */

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            wait(0.1);

            i2c.read ((addr_gu + 0x01), crdata, 3, true);

        }//if
        wait(0.1);
    }//While

}

/*
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte
    char crdata[6];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    //int     i;
    //float   fdata[4][4];//ファイル出力用
    //short   sdata[4];
    //short   s;

    read_regnum();//CAL登録No.読込
    read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

    auto_int_hyouji();

    //dac_init(); //DAC 初期化

    //gu-D タッチスイッチ読み出し動作設定 p49
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

    wait(0.1);

    Jyushin = i2c.read ((addr_gu + 0x01), crdata, 3, true);

    while(1) {

        wait(0.1);

        crdata[0] = 0;
        crdata[1] = 0;
        crdata[2] = 0;

        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if ( crdata[0] == 0x11 && crdata[2] == 1 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            cswnum = crdata[1]; //スイッチ番号
            //cswdata = crdata[2];//ON/OFF情報

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x00;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            //SWの番号(位置)
            if ( cswnum == 7 ) {

                gu_Button_power_off();//電源ボタンイメージ反転表示
                wait(0.5);

                led_off();//LED全消灯

                return;//この関数を抜ける

            }

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            wait(0.1);

            i2c.read ((addr_gu + 0x01), crdata, 3, true);

        } else if ( sw_start == 0 ) { //if

            auto_int_hyouji();

            gu_cursor(0,2);
            gu_print1("Please Wait..");
            gu_fontsize(2);

            read_regnum();//CAL登録No.読込

            read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

            auto_meas( number_of_channels );//2個測定

            hantei( number_of_channels );//判定LED

            wait(0.5);

            gu_fontsize(1);
            gu_cursor(0,2);
            gu_print1("READY           ");

        }
        wait(0.1);
    }//While
}
*/

/*
void auto_run()
{
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte
    char crdata[6];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    //int     i;
    //float   fdata[4][4];//ファイル出力用
    //short   sdata[4];
    //short   s;

    read_regnum();//CAL登録No.読込
    read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

    auto_int_hyouji();

    //dac_init(); //DAC 初期化

    //gu-D タッチスイッチ読み出し動作設定 p49
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

    wait(0.1);

    Jyushin = i2c.read ((addr_gu + 0x01), crdata, 3, true);

    while(1) {

        wait(0.1);

        crdata[0] = 0;
        crdata[1] = 0;
        crdata[2] = 0;

        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if ( crdata[0] == 0x11 && crdata[2] == 1 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            cswnum = crdata[1]; //スイッチ番号
            //cswdata = crdata[2];//ON/OFF情報

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x00;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            //SWの番号(位置)
            if ( cswnum == 7 ) {

                gu_Button_power_off();//電源ボタンイメージ反転表示
                wait(0.5);

                led_off();//LED全消灯

                return;//この関数を抜ける

            } else {

                auto_int_hyouji();

                gu_cursor(0,2);
                gu_print1("Please Wait..");
                gu_fontsize(2);

                read_regnum();//CAL登録No.読込

                read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

                auto_meas( number_of_channels );//2個測定

                hantei( number_of_channels );//判定LED

                wait(0.5);

                gu_fontsize(1);
                gu_cursor(0,2);
                gu_print1("READY           ");

            } //else if

            //gu-D タッチスイッチ読み出し動作設定 p49
            cmd_gu[0]= 0x1F;
            cmd_gu[1]= 0x4B;
            cmd_gu[2]= 0x18;
            cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2解除
            i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

            wait(0.1);

            i2c.read ((addr_gu + 0x01), crdata, 3, true);

        }//if

        wait(0.1);

    }//While

}
*/

/*********************************

    Auto Mode (Sub)

*********************************/
void meas_sub()
{
    auto_int_hyouji();

    gu_cursor(0,2);
    gu_print1("Please Wait..");
    gu_fontsize(2);

    //STX受信待ち抜け割込みイネーブル
    oneshot5.attach(&seq_timeout, 10);

    //シーケンサからEXT受信するまでループ
    /*
    while(seq_name[0] == 2){
        if(seq_name[3] == 3){
            break;
        }
        wait(0.5);
    }//while
    */
    
    while(seq_name[0] == 50){
        if(seq_name[3] == 51){
            break;
        }
        wait(0.5);
    }//while

    oneshot5.detach();

    read_regnum();//CAL登録No.読込

    read_caliber(&calinfo,reg_num);//指定したCAL登録No.の情報を読込後、calinfoへ代入

    auto_meas( number_of_channels );//2個測定

    hantei( number_of_channels );//判定LED
    
    seq_serialsend();//デバック用シーケンサ通信関数呼出
    
    
    //STX,EXT初期化
    seq_name[0] = 2;
    seq_name[3] = 3;
        
    wait(0.5);

    gu_fontsize(1);
    gu_cursor(0,2);
    gu_print1("READY           ");

}

/*******************************************************************************

    Auto Mode/SEQ Mode (sub)
    自動測定
    char noc -> 総測定数 1~4

*******************************************************************************/
void auto_meas(char noc)
{
    int     x[4] = {0,0,128,128};   //GU_D x座標 4個測定時の表示スタート位置
    int     y[4] = {5,11,5,11};     //GU_D y座標 4個測定時の表示スタート位置
    int     iy  ;                   //GU_D y座標 2個測定時の表示スタート位置
    int     i;
    short   sdata[4];

    iy = 4;//GU_D 2個測定時の測定値の表示開始位置 y座標

    if ( noc > 4 ) {
        noc = 4;
    }

    //値の初期化
    for ( i = 0; i <= 3; i++) {
        I[i] = 0;
        R[i] = 0;   //ver 1.1.1
        iop[i] = 0;
        voc[i] = 0;
        ocp[i] = 0;
    }

    //判定用LED消灯
    led_off();

    //電源投入
    for ( i = 0; i <= ( noc - 1 ); i++) {
        dac_out( calinfo.vss_iop,i); //Vss設定 DAC_A~D
    }

    wait( wait_poweron );//パワーブレイク復帰待機?

    //Reset DUT
    for ( i = 0; i <= ( noc -1 ); i++) {
        io_reset[i] = 1; //R = VDD
    }

    wait(time_reset); 

    for ( i = 0; i <= ( noc -1 ); i++) {
        io_reset[i] = 0; //R = "OPEN"
    }

    //抵抗測定
    for ( i = 0; i <= ( noc -1 ); i++ ) {
        R[i] = meas_resistor(i);
    }

    //display GU_D
    if ( number_of_channels <= 2 ) { //2個測定の時の表示
        gu_fontsize(2);
        gu_cursor(0,iy);
        gu_print1("[ch.1]");
        gu_cursor(128,iy);
        gu_print1("[ch.2]");
        //CH.1 表示
        gu_cursor(0, iy + 2);
        gu_print1("R     ");
        display_resistor( R[0] );
        //CH.2 表示
        gu_cursor(128, iy + 2);
        gu_print("R     ");
        display_resistor( R[1] );
    } else if( number_of_channels >= 3) { //3.4個測定の時の表示
        gu_fontsize(1);
        gu_cursor(x[0],y[0]);
        gu_print1("ch.1");
        gu_cursor(x[1],y[1] );
        gu_print1("ch.2");
        gu_cursor(x[2],y[2]);
        gu_print1("ch.3");

        if ( number_of_channels == 4 ) {
            gu_cursor(x[3],y[3]);
            gu_print1("ch.4");
        }

        //CH.1~4 表示
        for ( i = 0; i <= ( number_of_channels - 1 ); i++) {
            gu_cursor( x[i], y[i] + 1 );//x座標指定
            gu_print1("R      ");
            display_resistor( R[i] );
        }
    }

    //iop測定
    wait(calinfo.wait_iop);//Vss印加~リセット後からiop測定までの待機時間

    meas_current_automode( noc );//電流測定サブ 測定値をI[]へ代入

    for( i = 0; i <= ( noc - 1) ; i++) {
        iop[i] = I[i];
    }

    //display GU_D
    if ( number_of_channels <= 2 ) { //2個測定の時の表示
        gu_cursor(0, iy + 4 );//IOP測定値表示位置指定
        gu_print1("Iop   ");
        gu_putdeci(&iop[0]);
        gu_cursor(128, iy + 4 );
        gu_print1("Iop   ");
        gu_putdeci(&iop[1]);
    } else {
        //CH.1~4 表示
        for ( i=0; i <= ( number_of_channels - 1 ); i++) {
            gu_cursor( x[i], y[i] + 2 ); //x座標指定
            gu_print1("Iop   ");
            gu_putdeci(&iop[i]);
        }
    }

    wait(0.01);

    //過充電防止時電流測定
    for ( i = 0; i <= ( noc - 1 ); i++) {
        dac_out( calinfo.vss_ocp,i); //Vss設定 DAC_A~D //ver1.1.2
    }

    wait( calinfo.wait_ocp );

    meas_current_automode( noc );

    for( i = 0; i <= ( noc - 1) ; i++) {
        ocp[i] = I[i];
    }

    //display GU_D
    if ( number_of_channels <= 2 ) { //2個測定の時の表示
        gu_cursor(0, iy + 6 );//IOP測定値表示位置指定
        gu_print1("OCP   ");
        gu_putdeci(&ocp[0]);
        gu_cursor(128, iy + 6 );
        gu_print1("OCP   ");
        gu_putdeci(&ocp[1]);
    } else {
        //CH.1~4 表示
        for ( i=0; i <= ( number_of_channels - 1 ); i++) {
            gu_cursor( x[i], y[i] + 3 ); //x座標指定
            gu_print1("OCP   ");
            gu_putdeci(&ocp[i]);
        }
    }

    //VOC測定
    for ( i = 0; i <= ( noc - 1 ); i++) {
        dac_out( calinfo.vss_voc,i); //Vss設定 DAC_A~D
    }

    wait( wait_voc_1 );

    //Reset DUT
    for ( i = 0; i <= ( noc -1 ); i++) {
        io_reset[i] = 1; //R = VDD
    }

    wait( calinfo.wait_voc );//ver3

    for ( i = 0; i <= ( noc -1 ); i++ ) {

        voc[i] = meas_voltage(i);
        sdata[i] = voc[i] * -1;

    }

    //display GU_D
    if ( number_of_channels <= 2 ) { //2個測定の時の表示
        gu_cursor(0, iy + 8 );//IOP測定値表示位置指定
        gu_print1("Voc   ");
        gu_putdeck(&sdata[0]);
        gu_print1("V");
        gu_cursor(128, iy + 8 );
        gu_print1("Voc   ");
        gu_putdeck(&sdata[1]);
        gu_print1("V");
    } else {
        //CH.1~4 表示
        for ( i=0; i <= ( number_of_channels - 1 ); i++) {
            gu_cursor( x[i], y[i] + 4 );//x座標指定
            gu_print1("Voc   ");
            gu_putdeck(&sdata[i]);
            gu_print1("V");
        }
    }

    //R = "L"
    for ( i = 0; i <= ( noc -1 ); i++) {
        io_reset[i] = 0; //R = "OPEN"
    }

    wait(0.1);

    //Vss=0V
    for ( i = 0; i <= ( noc - 1 ); i++) {
        dac_out( 0, i );//Vss設定 DAC_A~D
    }

    //ファイルオープン
    mkdir("/sd/mydir", 0777);

    FILE *fp = fopen("/sd/mydir/iop.csv", "ab+");//ディレクトリとファイル名の指定,追加モード

    if(fp == NULL) {
        /* ver1.1.3
        gu_fontsize(1);
        gu_cursor(0,2);
        gu_print1("Could not open file for SD card");
        */
    } else {
        for ( i = 0; i <= ( noc - 1 ); i++) {
            fdata[i][0] = iop[i] * 0.01;    //1bitあたり0.01uA
            fdata[i][1] = ocp[i] * 0.01;    //1bitあたり0.01uA
            fdata[i][2] = voc[i] * 0.001;   //1bitあたり0.001V
        }

        for( i = 0; i <= ( noc - 1 ); i++) {

            switch ( i ) {
                case 0:
                    fprintf(fp, "CH.1");
                    break;
                case 1:
                    fprintf(fp, "CH.2");
                    break;
                case 2:
                    fprintf(fp, "CH.3");
                    break;
                case 3:
                    fprintf(fp, "CH.4");
                    break;
            }

            fprintf(fp, " ");//excel 区切り位置
            if ( R[i] < res_vref && R[0] >= 0 ) {
                fprintf(fp, "%d", R[i]);
            } else {
                fprintf(fp,"OL");
            }
            fprintf(fp, " ");
            fprintf(fp, "%f", fdata[i][0]);
            fprintf(fp, " ");
            fprintf(fp, "%f", fdata[i][1]);
            fprintf(fp, " ");
            fprintf(fp, "%f", fdata[i][2]);
            fprintf(fp, " ");
        }//for

        //ファイルクローズ
        fprintf(fp, "\n");
        fclose(fp);
    }

}

/*********************************

    電流測定(iop/voc共通)
    char amount;//測定数

*********************************/
void meas_current_automode(char amount)   //a quantity of measuring channel
{
    int i;

    //amount = number_of_channels;

    //set range
    for ( i = 0; i <= ( amount - 1 ); i++)
        range[i] = 1;   //range 10uA

    wait(0.1);

    //discharge condenser
    for ( i = 0; i <= ( amount - 1 ); i++)
        houden[i] = 1;  //discharge condenser

    wait(time_discharge);//discharge time

    ch_num = 0;
    select_ich( ch_num ); //select channel that mesuring current
    houden[0] = 0; //start integral

    oneshot1.attach ( &flip_ch1, time_integral );

    if ( amount >= 2 ) {
        wait(0.1);
        houden[1] = 0;
        oneshot2.attach ( &flip_ch2, time_integral );
    }

    if ( amount >= 3 ) {
        wait(0.1);
        houden[2] = 0;
        oneshot3.attach ( &flip_ch3, time_integral );
    }

    if ( amount == 4 ) {
        wait(0.1);
        houden[3] = 0;
        oneshot4.attach ( &flip_ch4, time_integral );
    }

    wait( time_integral + 0.3 );//wait Timeout

    //discharge condenser
    for ( i = 0; i <= ( amount - 1 ); i++)
        houden[i] = 1;  //discharge condenser

    wait(time_discharge);//discharge time

    //not discharge condenser
    for ( i = 0; i <= ( amount - 1 ); i++)
        houden[i] = 0;

    //set range
    for ( i = 0; i <= ( amount - 1 ); i++)
        range[i] = 0;  //range 1mA

    oneshot1.detach();
    oneshot2.detach();
    oneshot3.detach();
    oneshot4.detach();

}

/*********************************
    DAC 初期設定
    LDACレジスタの設定
    内部リファレンス電圧のセットアップ
    入力シフトレジスタ:
    0011 1000 0000 0000 0000 0001
    (0x3F0001)
*********************************/
void dac_init()
{

    //内部リファレンス電圧のセットアップ
    wdata[0] = 0x38;
    wdata[1] = 0x00;
    wdata[2] = 0x01;//

    i2c.write ( addr_dac, wdata, 3);

    wait(0.1);

    //LDAC設定
    wdata[0] = 0x30;
    wdata[1] = 0x00;
    wdata[2] = 0x0F;//

    i2c.write ( addr_dac, wdata, 3);

}

/**************************************
    DAC 電圧印加
    Vout = 2 * Vref(2.5V) * ( D /2^2 )
    mvolt[mV] 0~5000で設定
    addrは、0x00~03.全チャネルは0x07で指定
**************************************/
void dac_out(short mvolt, char addr)   //addr DACA:0x00 DACB:0x01 DACC:0x02 DACD:0x03 allDACs:0x07
{
    char    command;//1byte
    short   dacdata;//2byte

    command = 0x02;//write to input register n 仕様書p25参照

    dacdata = mvolt * 4095 / 2 / dac_vref ; //12bit mvolt[mV] 0~5000で設定する

    dacdata = dacdata << 4; //後ろ4bitはdon't care bit

    wdata[0] = command << 3 | addr; //1byte
    wdata[1] = dacdata >> 8 ; //1byte
    wdata[2] = dacdata & 0xFF;//1byte

    i2c.write(addr_dac, wdata, 3);

}
/*********************************
    ADC測定し、平均値を算出する

    貰う値:平均値の分母
    渡す値:平均値
*********************************/
void compute_adc(int adc_con, long *avg)   //(ADCのCONFIG, 計算結果)
{

    //short    sdata[10];//2byte
    long    ldata[10];//4byte
    long    nu;//平均値の分子 4byte
    long    max;
    long    min;
    char    i;
    char    x;
    //int     n;

    x = 10;

    wdata[0] = adc_con; //ADC configuration data チャンネルの選択など
    i2c.write( addr_ADC1, wdata, 1 );
    wait(0.1);

    //平均値の母数の数、測定を実施。
    for( i=0; i<=(x-1); i++) {

        i2c.read( addr_ADC1 + 0x01, rdata, 3);
        //2byte結合
        ldata[i] = rdata[0] & 0xFF;
        ldata[i] = ( ldata[i] << 8 ) | rdata[1];

        if ( ldata[i] >= 0x8000 ) {
            ldata[i] = ldata[i] | 0xFFFF0000; //4byteの補数へ変換
        }

        wait(0.05);

    }//for

    //最大値を取得
    max = ldata[0];
    for ( i=0; i<=(x-2); i++) {
        if ( ldata[i+1] > ldata[i]) {
            max = ldata[i+1];
        }
    }
    //最小値
    min = ldata[0];
    for ( i=0; i<=(x-2); i++) {
        if ( ldata[i+1] < ldata[i]) {
            min = ldata[i+1];
        }
    }

    //平均値
    nu = 0x00000000;    //4byte
    for ( i=0; i<=(x-1); i++) {
        nu = nu + ldata[i];
    }

    *avg = ( nu - max - min ) / ( x - 2 );

}


/**************************************
    2バイトを10進数で表示する 0~65535
    format *0.000
    mV→uAへ変換(1/1000)
    プリアンプ GAIN 1/5
    ADC_LSB:0.25mV
    積分時間 2s
    容量 20uF
**************************************/
void gu_putdeci(float* idata)
{

    float uA; //ver1.1.4
    long y; //ver1.1.4
    long x; //ver1.1.4

    //千分の一、四捨五入。
    if ( *idata > 0 ) {
        uA = *idata + 0.5;
    } else {
        uA = *idata - 0.5;
    }

    x = uA; //小数点以下切り捨て

    //四捨五入 up to here

    //プラスマイナスの表示
    if( x >= 0 ) {
        wdata[0] = 0x2B;//ascii "+"
        i2c.write(addr_gu, wdata, 1);

        y = x;

    } else {
        wdata[0] = 0x2D;//ascii "-"
        i2c.write(addr_gu, wdata, 1);

        y = ( ~x ) + 0x01;//2の補数
    }

    //y = y * 5 * 0.25;//プリアンプのGAINが1/5なのでここで5倍.ADC14bit分解能で、1bitあたり0.25mv

    wdata[0] = (( y / 1000 ) % 10 ) + 0x30;

    if( wdata[0] == 0x30 )//2桁目が零の場合、"0"を表示しない。
        wdata[0] = 0x20;

    wdata[1] = (( y / 100 ) % 10 ) + 0x30;
    wdata[2] = 0x2E;//ASCII "."
    wdata[3] = (( y / 10 ) % 10 ) + 0x30;
    wdata[4] = ( y % 10 ) + 0x30;

    //ver1.2.5
    //i2c.write(addr_gu, wdata, 5);
    //gu_print1("uA");
    
    if ( *idata > O_L * -100 && *idata < O_L * 100 ){

        i2c.write(addr_gu, wdata, 5);
        gu_print1("uA");
        
    }else{
        
        gu_print1("O.L");
    
    } 
    //upto

}

/**************************************
    2バイトを10進数で表示する 0~65535
    format *0.000
    mV→uAへ変換(1/1000)
    プリアンプ GAIN 1/5
    ADC_LSB:0.25mV
    シャント抵抗1kΩ
**************************************/
void gu_putdeci_mA(float* idata)
{
    float uA; //ver1.1.4
    long y; //ver1.1.4
    long x; //ver1.1.4

    //千分の一、四捨五入。
    if ( *idata > 0 ) {
        uA = *idata + 0.5;
    } else {
        uA = *idata - 0.5;
    }

    x = uA; //小数点以下切り捨て

    //四捨五入 up to here

    //プラスマイナスの表示
    if( x >= 0 ) {
        wdata[0] = 0x2B;//ascii "+"
        i2c.write(addr_gu, wdata, 1);

        y = x;

    } else {
        wdata[0] = 0x2D;//ascii "-"
        i2c.write(addr_gu, wdata, 1);

        y = ( ~x ) + 0x01;//2の補数
    }

    //y = y * 5 * 0.25;//プリアンプのGAINが1/5なのでここで5倍.ADC14bit分解能で、1bitあたり0.25mv

    /*
    wdata[0] = (( *y / 100000 ) % 10 ) + 0x30;

    if( wdata[0] == 0x30 )//3桁目が零の場合、"0"を表示しない。
        wdata[0] = 0x20;
    */

    wdata[0] = (( y / 1000 ) % 10 ) + 0x30;

    if( wdata[0] == 0x30 )//2桁目が零の場合、"0"を表示しない。
        wdata[0] = 0x20;

    wdata[1] = (( y / 100 ) % 10 ) + 0x30;
    wdata[2] = 0x2E;//ASCII "."
    wdata[3] = (( y / 10 ) % 10 ) + 0x30;
    wdata[4] = ( y % 10 ) + 0x30;

    i2c.write(addr_gu, wdata, 5);

    gu_print1("mA");

}

/**************************************
    2バイトを10進数で表示する 0~65535
    1/1000倍 format *0.000
    mV→V Ω→kΩ
**************************************/
void gu_putdeck(short* x)
{

    short num;

    //プラスマイナスの表示
    if( *x >= 0 ) {
        wdata[0] = 0x2B;//ascii "+"
        i2c.write(addr_gu, wdata, 1);
        num = *x;

    } else {
        wdata[0] = 0x2D;//ascii "-"
        i2c.write(addr_gu, wdata, 1);

        //*x = ( ~*x ) + 0x01;//2の補数
        num = *x * -1;
    }

    wdata[0] = (( num / 10000 ) % 10 ) + 0x30;

    if( wdata[0] == 0x30 )//2桁目が零の場合、"0"を表示しない。
        wdata[0] = 0x20;

    wdata[1] = (( num / 1000 ) % 10 ) + 0x30;
    wdata[2] = 0x2E;//ASCII "."
    wdata[3] = (( num / 100 ) % 10 ) + 0x30;
    wdata[4] = (( num / 10 ) % 10 ) + 0x30;
    //wdata[5] = ( num % 10 ) + 0x30;

    i2c.write(addr_gu, wdata, 5);

}

/********************************

    判定 LED点灯

********************************/
void hantei(char noc)
{
    int i;

    //エラーフラグ
    for ( i=0; i<= 3 ; i++) {
        err_f[i] = 0;
    }

    //ver1.2
    if (DEB_EN == 1) {
        voc[0] = 3100;//[mV]
        ocp[0] = -0.4*100;//[uA] 0.1uAのときocp[]の値は10
        iop[0] = 16.5*100;//[uA] 0.1uAのときicp[]の値は10
        voc[1] = 3100;//[V]
        ocp[1] = 0.4*100;//[uA]
        iop[1] = 16.5*100;//[uA]
    }
    //upto

    for ( i = 0; i <= ( noc - 1 ); i++) {

        /*ver1.1.3 規格設置値=0の場合は判定しない*/
        if( voc[i] < calinfo.low_limit_voc && calinfo.low_limit_voc != 0) {
            err_f[i] = 1;
        }

        if( iop[i] < calinfo.low_limit_iop ) {
            err_f[i] = 1;
        }

        if( ocp[i] > calinfo.low_limit_ocp ) {
            err_f[i] = 1;
        }

        //ver1.2.2
        if( ocp[i] < calinfo.up_limit_ocp && calinfo.up_limit_ocp != 0) {
            err_f[i] = 1;
        }

        if( R[i] < calinfo.low_limit_resistor && calinfo.low_limit_resistor != 0 ) {
            err_f[i] = 1;
        }

        if( R[i] > calinfo.up_limit_resistor && calinfo.up_limit_resistor != 0 ) {
            err_f[i] = 1;
        }

        if( err_f[i] == 1) {
            led_red[i] = 1;
        } else {
            led_green[i] = 1;
        }

        if ( SEQ_EN == 1 && err_f[i] == 0 ) {
            /*** ver3
            seq_hantei[i] = 1;
            ***/
            seq_out[i] = 1;
        }

        //ver1.2.3
        char *print_text;

        if(DEB_EN == 1) {

        gu_fontsize(1);
        gu_cursor(0,2);
        gu_print1("                ");

            if(err_f[i] == 1) {

                switch(i){
                    case 0: 
                        print_text="FAIL DUT1";
                        break;
                    case 1: 
                        print_text="FAIL DUT2";
                        break;
                }

                gu_fontsize(1);
                gu_cursor(0,2);
                gu_print1(print_text);
                wait(1);
            }
            if(err_f[i] == 0) {

                
                switch(i){
                    case 0: 
                        print_text="PASS DUT1";
                        break;
                    case 1: 
                        print_text="PASS DUT2";
                        break;
                }

                gu_fontsize(1);
                gu_cursor(0,2);
                gu_print1(print_text);

                wait(1);
            }
        }
        //upto

    }//for


}

/*******************************************************************************

    measure voltage
    測定CHを指定して、電圧値Rを返す
    char ch 0~3 -> 1ch ~ 4ch

        ver3.0.0    リレー制御シーケンスを追加

*******************************************************************************/
short meas_voltage(char ch)//ch 0~3 -> 1ch ~ 4ch
{
    char    com;
    short   sdata;

    switch(ch) {
        case 0:
            /*** ver3 *****************/
            rlen[4] = 1; //RLEN5="H"
            wait(ton_rr);
            /**************************/
            
            com = adc_config(2,0);//ch1(adc),12bit
            i2c.write( addr_ADC1, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC1);
            break;
            
        case 1:
        
            /*** ver3 *****************/
            rlen[5] = 1; //RLEN6="H"
            wait(ton_rr);
            /**************************/
        
            com = adc_config(3,0);//ch2(adc),12bit
            i2c.write( addr_ADC1, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC1);
            break;
            
        case 2:

            /*** ver3 *****************/
            rlen[6] = 1; //RLEN7="H"
            wait(ton_rr);
            /**************************/
            
            com = adc_config(2,0);//ch1(adc),12bit
            i2c.write( addr_ADC2, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC2);
            break;
            
        case 3:
        
            /*** ver3 *****************/
            rlen[7] = 1; //RLEN8="H"
            wait(ton_rr);
            /**************************/
            
            com = adc_config(3,0);//ch2(adc),12bit
            i2c.write( addr_ADC2, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC2);
            break;
            
    }// end switch
    
    /*** ver3 ***/
    //電圧測定用リレーを全てオフ
    for (int i = 4; i <= 7; i++){
        rlen[i] = 0;
    }
    wait(toff_rr);
    /************/

    //プリアンプ倍率を代入して、電圧値を算出する(単位はmV)
    sdata = sdata * 5;//プリアンプ倍率

    return ( sdata );
}


/*******************************************************************************

    measure resistor
    
        測定CHを指定して、抵抗測定値Rを返す
        char ch 0~3 -> 1ch ~ 4ch

        ver3.0.0 リレー制御追加

*******************************************************************************/
short meas_resistor(char ch)//ch 0~3 -> 1ch ~ 4ch
{
    char    com;
    short   sdata;

    switch(ch) {
        case 0:
            /*
            //ver1.2.0
            if (RL_EN == 1) {
                io[6] = 1; //外付けリレーON
                wait(TIME_RELAY_ON);
            }
            //up to here
            */
            
            /*** ver3 *****************/
            rlen[0] = 1; //RLEN1="H"
            wait(ton_rr);
            /**************************/

            com = adc_config(0,0);//ch1(adc),12bit
            i2c.write( addr_ADC1, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC1);
            
            /*
            //ver1.2.0 relay off
            if (RL_EN == 1) {
                io[6] = 0 ;
            }
            */

            break;

        case 1:
        
            /*
            //ver1.2.0
            if (RL_EN == 1) {
                io[7] = 1; //外付けリレーON
                wait(TIME_RELAY_ON);
            }
            //up to here
            */

            /*** ver3 *****************/
            rlen[1] = 1; //RLEN2="H"
            wait(ton_rr);
            /**************************/

            com = adc_config(1,0);//ch2(adc),12bit
            i2c.write( addr_ADC1, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC1);
            
            /*
            //ver1.2.0
            if (RL_EN == 1) {
                io[7] = 0;
            }
            */

            break;

        case 2:
            /*** ver3 *****************/
            rlen[2] = 1; //RLEN3="H"
            wait(ton_rr);
            /**************************/        

            com = adc_config(0,0);//ch1(adc),12bit
            i2c.write( addr_ADC2, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC2);
            
            break;
            
        case 3:
            /*** ver3 *****************/
            rlen[3] = 1; //RLEN4="H"
            wait(ton_rr);
            /**************************/
        
            com = adc_config(1,0);//ch2(adc),12bit
            i2c.write( addr_ADC2, &com, 1);
            wait(0.1);
            sdata = read_adc(addr_ADC2);
            
            break;
            
    }// end switch

    /*** ver3 *********************/
    //抵抗測定用リレーを全てオフ
    for (int i = 0; i <= 3; i++){
        rlen[i] = 0;
    }
    wait(toff_rr);
    /*****************************/

    //検出用抵抗値を代入して、測定抵抗値を算出する(単位はmV,Ω)
    if ( sdata < res_vref ) {
        sdata =( rsense * sdata ) / ( res_vref - sdata);
    } else {
        sdata = res_vref;//overload
    }

    return ( sdata );
}


/*********************************

    display resistor
    測定抵抗値を表示する

*********************************/
void display_resistor(short sdata)//測定値を表示する。
{
    if ( sdata < res_vref && sdata >= 0 ) {
        gu_putdec(&sdata);
    } else {
        gu_print1(" OL ");//overload
    }
    gu_onebyte(0xEA);//ohm
}

/**************************************
    4バイトを10進数で表示する 0~9999
**************************************/
void gu_putdec(short* x)
{

    char cmd[4];

    //cmd[0] = (( *x / 100000 ) % 10 ) + 0x30;
    cmd[0] = (( *x / 1000 ) % 10 ) + 0x30;
    cmd[1] = (( *x / 100 ) % 10 ) + 0x30;
    cmd[2] = (( *x / 10 ) % 10 ) + 0x30;
    cmd[3] = ( *x % 10 ) + 0x30;

    i2c.write(addr_gu, cmd, 4);

}
/*********************************

    LED 照度
    設定読込~反映
    //メモリから設定値を読み出して、LEDのPWMのDutyを設定する
    //LED1設定値&LED2設定値の計2Byte読込

*********************************/
void read_syoudo(char* c)
{
    //char cmd;       //gu-DへのI2Cコマンド用配列 1byte0
    //char csyoudo[4];//led出力用pwm duty 設定比1バイト255段階

    float duty_pwm; //pwm パーセンテージ
    int i;

    //メモリ10h番地(照度設定データ)読み出し
    //cmd[0] = 0x10;  //ver3
    //Sequential Read

    i2c.write (eeprom_adrs, adrs_syoudo, 2,true);   //ver3 repeated start,true - do not send stop condition
    //i2c.write (slave_adrs, &cmd, 1,true);         //ver3 send 1 byte remove stop condition
    slave_adrs = eeprom_adrs + 0x01;                //ver3 read mode
    i2c.read (slave_adrs, rdata, 4);                //read 4 byte

    for ( i = 0; i <=3; i++) {
        c[i] = rdata[i];
    }

    //set pwm duty
    for ( i = 0; i <= ( number_of_channels - 1 ); i++) {

        if(c[i] == 0x00) {
            c[i] = 0x32;
        }

        duty_pwm = COP * c[i];

        leds[i].write (duty_pwm);//Set Duty
    }
}
/*********************************

    LED 照度調整 (Main)

*********************************/
void adjust_illumination()
{
    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte0
    //char *pcmd = cmd_gu;
    //char msg;
    //char *pmsg = &msg;
    char crdata[3];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F gu-D スイッチNo.
    char cswdata; // 0x00 or 0x01 ONかOFFか
    char *pcswnum = &cswnum;
    char *pcswdata = &cswdata;
    char csyoudo[4];//led出力用pwm duty 設定比1バイト255段階
    char ch;
    float duty_pwm;//pwm パーセンテージ
    int i;
    int x[4] = {64,64,192,192}; //レベル値の表示位置 x座標
    int y[4] = {2,4,2,4}; //レベル値の表示位置 y座標
    //
    //EEPROMから照度データ読込とPWMDUTYセット
    read_syoudo( csyoudo );
    //
    //画面表示
    gu_cls();//画面のクリア
    gu_fontsize(2);
    gu_print1("Adjust illumination ");
    //照度レベルを256段階で表示
    //LED1
    gu_cursor(0,16/8);
    gu_print1("LED1 Lv ");
    //LED2
    gu_cursor(0,32/8);
    gu_print1("LED2 Lv ");
    //LED3
    if( number_of_channels >= 3 ) {
        gu_cursor(128,2);
        gu_print1("LED3 Lv ");
    }
    //LED4
    if( number_of_channels >= 4 ) {
        gu_cursor(128,4);
        gu_print1("LED4 Lv ");
    }
    //
    for ( i = 0; i <= ( number_of_channels - 1 ); i++) {

        gu_cursor(x[i],y[i]);

        cmd_gu[0] = ((csyoudo[i] / 100) & 0xFF) + 0x30;
        cmd_gu[1] = (csyoudo[i] - (csyoudo[i] / 100) * 100) / 10 + 0x30;
        cmd_gu[2] = ((csyoudo[i] % 10) & 0xFF) + 0x30;
        i2c.write(addr_gu, cmd_gu, 3);
    }

    //
    gu_fontsize(1);
    gu_cursor(0,56/8);
    gu_print1("LED1");
    gu_cursor(32,56/8);
    gu_print1("fine");
    gu_cursor(64,56/8);
    gu_print1("LED2");
    gu_cursor(96,56/8);
    gu_print1("fine");

    if( number_of_channels >= 3) {
        gu_cursor(128,56/8);
        gu_print1("LED3");
        gu_cursor(160,56/8);
        gu_print1("fine");
    }
    if( number_of_channels >= 4) {
        gu_cursor(192,56/8);
        gu_print1("LED4");
        gu_cursor(224,56/8);
        gu_print1("fine");
    }
    //
    //gu-D タッチスイッチ読み出し動作設定 p49
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;//SW状態変化時自動送信モード2
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49
    //
    //ボタンイメージの表示
    for ( i = 17; i < 17 + ( number_of_channels * 2 ); i++) {
        gu_button_up(i);
    }
    for ( i = 25; i < 25 + ( number_of_channels * 2 ); i++) {
        gu_button_down(i);
    }
    gu_Button_power_on();//show button
    wait(0.2);

    while(1) {

        i2c.read ((addr_gu + 0x01), crdata, 3);

        if (crdata[0] == 0x11 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            *pcswnum = crdata[1]; //スイッチ番号
            *pcswdata = crdata[2];//ON/OFF情報

            if (cswdata == 0x01) { //タッチしたならば

                switch ( number_of_channels ) { //ver1.1.0

                    case 1:
                    case 2:
                        if ( cswnum >= 20 && cswnum <= 23 )
                            cswnum = 0;

                        if ( cswnum >= 28 && cswnum <= 31 )
                            cswnum = 0;

                        break;

                    case 3:
                        if ( cswnum >= 22 && cswnum <= 23 )
                            cswnum = 0;

                        if ( cswnum >= 30 && cswnum <= 31 )
                            cswnum = 0;

                        break;

                } //switch

                switch( cswnum ) { //SWの番号(位置)

                    case 22:
                    case 20:
                    case 16:
                    case 18:

                        ch = ( cswnum - 16 ) / 2; //SWnoから選択したLEDNoの算出

                        gu_button_up_on( cswnum + 1 );
                        wait(0.2);
                        gu_button_up( cswnum + 1 );
                        wait(0.1);

                        if(csyoudo[ch] <= 0xEF ) {
                            csyoudo[ch] = csyoudo[ch] + 0x0A;
                        }

                        break;

                    case 23:
                    case 21:
                    case 17:
                    case 19:

                        ch = ( cswnum - 17 ) / 2; //SWnoから選択したLEDNoの算出

                        gu_button_up_on( cswnum + 1 );
                        wait(0.2);
                        gu_button_up( cswnum + 1 );
                        wait(0.1);

                        if(csyoudo[ch] <= 0xFF ) {
                            csyoudo[ch] = csyoudo[ch] + 0x01;
                        }

                        break;

                    case 24:
                    case 26:
                    case 28:
                    case 30:

                        ch = ( cswnum - 24 ) / 2; //SWnoから選択したLEDNoの算出

                        gu_button_down_on( cswnum + 1 );
                        wait(0.2);
                        gu_button_down( cswnum + 1 );
                        wait(0.1);

                        if(csyoudo[ch] >= 0x0A ) {
                            csyoudo[ch] = csyoudo[ch] - 0x0A;
                        }

                        break;

                    case 25:
                    case 27:
                    case 29:
                    case 31:

                        ch = ( cswnum - 24 ) / 2; //SWnoから選択したLEDNoの算出

                        gu_button_down_on( cswnum + 1 );
                        wait(0.2);
                        gu_button_down( cswnum + 1 );
                        wait(0.1);

                        if(csyoudo[ch] >= 0x01 ) {
                            csyoudo[ch] = csyoudo[ch] - 0x01;
                        }

                        break;

                    case 7 ://SW.8 保存ボタンを押すと現在のLED照度をEEPROMへ保存する

                        wdata[0] = adrs_syoudo[0]; //word address 書込み先頭アドレス指定
                        wdata[1] = adrs_syoudo[1];  //ver3

                        for ( i = 0; i <= ( number_of_channels - 1 ); i++) {
                            wdata[ i + 2 ] = csyoudo[i]; //DATA_LED i
                        }

                        Soushin = i2c.write (eeprom_adrs, wdata,( number_of_channels + 2 )); // ver3 全送信BYTE数は、書込みデータにBYTE ADDRESSの2byteを加算した数

                        if(Soushin == 0) {
                            gu_Button_power_off();//電源ボタンイメージ反転表示
                            wait(0.3);

                            return;//照度調整ルーチンを抜ける
                        }
                } //switch



                //PWMのDUTY設定

                for( i = 0; i <= ( number_of_channels - 1 ); i++) {
                    duty_pwm = COP * csyoudo[i];
                    leds[i].write (duty_pwm);//Set Duty
                }


                //照度レベルを256段階で表示
                //LED1
                gu_fontsize(2);

                for ( i = 0; i <= ( number_of_channels - 1 ); i++) {

                    gu_cursor(x[i],y[i]);

                    cmd_gu[0] = ((csyoudo[i] / 100) & 0xFF) + 0x30;
                    cmd_gu[1] = (csyoudo[i] - (csyoudo[i] / 100) * 100) / 10 + 0x30;
                    cmd_gu[2] = ((csyoudo[i] % 10) & 0xFF) + 0x30;
                    i2c.write(addr_gu, cmd_gu, 3);
                }
            }
        } //if

        wait(0.1);//gu-D 読込間隔の設定

    }
}

/*********************************

    サブ基板LED(判定用)全消灯

*********************************/
void led_off()
{
    int i;

    for( i = 0; i <= ( number_of_channels - 1 ); i++) {
        led_green[ i ] = 0;
        led_red[ i ] = 0;
    }

}
/*********************************

    Utility Main
    gu_D 輝度調整 タッチ感度調整

*********************************/
void utility()   //輝度調整サブルーチン
{

    char cmd_gu[32] ;   //gu-DへのI2Cコマンド用配列 1byte0
    //char *pcmd = cmd_gu;
    char clumi; //輝度設定用変数 01h<=n<=08h
    char* pclumi = &clumi; //ポインタの定義
    char msg;
    char *pmsg = &msg;
    char crdata[3];
    char cswnum; //SW_No. sw1->0x00 ~~ sw32->0x1F
    char cswdata; // 0x00 or 0x01
    char *pcswnum = &cswnum;
    char *pcswdata = &cswdata;
    //
    //メモリ00h番地(輝度設定データ)読み出し
    //wdata[0] = 0x00;
    //Soushin = i2c.write (eeprom_adrs, wdata, 1,true);    //読込先頭アドレス指定 ReStart
    Soushin = i2c.write (eeprom_adrs, adrs_kido, 2,true);    //ver3 読込先頭アドレス指定 2byte
    Jyushin = i2c.read ((eeprom_adrs + 0x01), rdata, 1);//read 1byte
    *pclumi = rdata[0];

    //輝度設定更新
    if(*pclumi==0x00 || *pclumi > 0x08) *pclumi=0x05;
    gu_luminance(pclumi);

    //画面表示
    gu_cls();//画面のクリア
    gu_print1("Set Display Brightness");
    gu_cursor(0,16/8);
    gu_print1("LEVEL ");
    *pmsg = *pclumi + 0x30;
    gu_print1(pmsg);

    gu_cursor(0,96/8); //ver1.1.0
    gu_print1("DELETE EEPROM_DATA");
    gu_set_button_font1(30,"del");

    //SW状態変化時自動送信モード2
    cmd_gu[0]= 0x1F;
    cmd_gu[1]= 0x4B;
    cmd_gu[2]= 0x18;
    cmd_gu[3]= 0x02;
    i2c.write(addr_gu, cmd_gu, 4); //gu-D タッチスイッチ読み出し動作設定 p49

    //ボタンイメージの表示
    gu_button_up(6);//show button
    gu_button_down(14);//show button
    gu_Button_power_on();//show button

    while(1) {

        i2c.read ((addr_gu + 0x01), crdata, 3, true);

        if (crdata[0] == 0x11 ) { //個別タッチスイッチ状態読み出しフォーマット。識別子11h。
            *pcswnum = crdata[1]; //スイッチ番号
            *pcswdata = crdata[2];//ON/OFF情報

            if (cswdata == 0x01) { //タッチしたならば
                switch( cswnum ) { //SWの番号(位置)
                    case 5 ://SW6
                        gu_button_up_on( 6 );
                        wait(0.2);
                        gu_button_up( 6 );
                        wait(0.1);

                        if(clumi < 8 ) *pclumi = *pclumi + 1;

                        break;

                    case 13 ://SW14
                        gu_button_down_on( 14 );
                        wait(0.2);
                        gu_button_down( 14 );
                        wait(0.1);

                        if(clumi >= 1 ) *pclumi = *pclumi - 1;

                        break;

                    case 29:  //SW30

                        gu_reverse(0x01);   //gu_リバース指定
                        gu_set_button_font1(30,"del");
                        gu_reverse(0x00);   //gu_リバース解除

                        erace_calinfo();

                        gu_set_button_font1(30,"del");

                        break;

                    case 0x07 ://保存ボタンを押すと現在の輝度をEEPROMへ保存する

                        //wdata[0] = 0x00 ; //word address 書込み先頭アドレス指定
                        //wdata[1] = *pclumi ; //DATA
                        
                        wdata[0] = adrs_kido[0];    //ver3
                        wdata[1] = adrs_kido[1];    //ver3                        
                        wdata[2] = *pclumi ;        //ver3
                        
                        Soushin = i2c.write (eeprom_adrs, wdata, 3); //ver3 

                        if(Soushin == 0) {
                            gu_Button_power_off();//電源ボタンイメージ反転表示
                            wait(0.5);
                            return;//輝度調整ルーチンを抜ける
                        }

                } //switch

                gu_luminance(pclumi);//輝度変更
                gu_cursor(0,16/8);
                gu_print1("LEVEL ");
                *pmsg = *pclumi + 0x30;
                gu_print1(pmsg);

            }
        } //if

        wait(0.1);//gu-D 読込間隔の設定

    }
}

/*********************************
    gu_D グラフィックデータ
*********************************/
char gu_Button_MODE_data[] = {
    0x7F,0xF0,0x80,0x08,0x80,0x0C,0x80,0x0A,0x80,0x0A,0x80,0x0A,0x80,0x0A,0x80,0x0A,
    0x80,0x0A,0x80,0x0A,0x80,0x0A,0x80,0x0A,0x7F,0xF2,0x20,0x02,0x1F,0xFC,0x00,0x00,
};

void gu_set_button(char sw_num,char* text)
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_drawButton(x,y,32,32, gu_Button_MODE_data );

    // Change Font Size
    gu_fontsize(2);
    // set font width
    gu_fontWidth(Proportional1);
    gu_print_dot( x + 8,y + 8,text);
    // Change Font Size
    gu_fontsize(1);
    // set font width
    gu_fontWidth(1);
}

void gu_set_button_font1(char sw_num,char* text)
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_drawButton(x,y,32,32, gu_Button_MODE_data );

    // Change Font Size
    gu_fontsize(1);
    // set font width
    gu_fontWidth(1);
    gu_print_dot( x + 2,y + 10,text);

}

char gu_Button_up_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x10,0x00,0x00,0x08,
    0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x18,0x04,
    0x20,0x00,0x38,0x04,0x20,0x00,0x78,0x04,0x20,0x00,0xF8,0x04,0x20,0x01,0xF8,0x04,
    0x20,0x03,0xF8,0x04,0x20,0x07,0xF8,0x04,0x20,0x0F,0xF8,0x04,0x20,0x1F,0xF8,0x04,
    0x20,0x1F,0xF8,0x04,0x20,0x0F,0xF8,0x04,0x20,0x07,0xF8,0x04,0x20,0x03,0xF8,0x04,
    0x20,0x01,0xF8,0x04,0x20,0x00,0xF8,0x04,0x20,0x00,0x78,0x04,0x20,0x00,0x38,0x04,
    0x20,0x00,0x18,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,
    0x10,0x00,0x00,0x08,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_button_up(char sw_num)
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_cursor( x, y/8 );
    gu_RealTimeImage(32, 32, gu_Button_up_data);
}

void gu_Button_up1()
{
    gu_cursor(224,8);
    gu_RealTimeImage(32, 32, gu_Button_up_data);
}

void gu_Button_up2()
{
    gu_cursor(192,8);
    gu_RealTimeImage(32, 32, gu_Button_up_data);
}

void gu_Button_up3()
{
    gu_cursor(160,8);
    gu_RealTimeImage(32, 32, gu_Button_up_data);
}

void gu_Button_up4()
{
    gu_cursor(128,8);
    gu_RealTimeImage(32, 32, gu_Button_up_data);
}

char gu_Button_down_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x10,0x00,0x00,0x08,
    0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x18,0x00,0x04,
    0x20,0x1C,0x00,0x04,0x20,0x1E,0x00,0x04,0x20,0x1F,0x00,0x04,0x20,0x1F,0x80,0x04,
    0x20,0x1F,0xC0,0x04,0x20,0x1F,0xE0,0x04,0x20,0x1F,0xF0,0x04,0x20,0x1F,0xF8,0x04,
    0x20,0x1F,0xF8,0x04,0x20,0x1F,0xF0,0x04,0x20,0x1F,0xE0,0x04,0x20,0x1F,0xC0,0x04,
    0x20,0x1F,0x80,0x04,0x20,0x1F,0x00,0x04,0x20,0x1E,0x00,0x04,0x20,0x1C,0x00,0x04,
    0x20,0x18,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,
    0x10,0x00,0x00,0x08,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_button_down(char sw_num)
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_cursor( x, y/8 );
    gu_RealTimeImage(32, 32, gu_Button_down_data);
}

void gu_Button_down1()
{
    gu_cursor(224,12);
    gu_RealTimeImage(32, 32, gu_Button_down_data);
}

void gu_Button_down2()
{
    gu_cursor(192,12);
    gu_RealTimeImage(32, 32, gu_Button_down_data);
}

void gu_Button_down3()
{
    gu_cursor(160,12);
    gu_RealTimeImage(32, 32, gu_Button_down_data);
}

void gu_Button_down4()
{
    gu_cursor(128,12);
    gu_RealTimeImage(32, 32, gu_Button_down_data);
}

char gu_Button_up_on_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xF8,
    0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xE7,0xFC,
    0x3F,0xFF,0xC7,0xFC,0x3F,0xFF,0x87,0xFC,0x3F,0xFF,0x07,0xFC,0x3F,0xFE,0x07,0xFC,
    0x3F,0xFC,0x07,0xFC,0x3F,0xF8,0x07,0xFC,0x3F,0xF0,0x07,0xFC,0x3F,0xE0,0x07,0xFC,
    0x3F,0xE0,0x07,0xFC,0x3F,0xF0,0x07,0xFC,0x3F,0xF8,0x07,0xFC,0x3F,0xFC,0x07,0xFC,
    0x3F,0xFE,0x07,0xFC,0x3F,0xFF,0x07,0xFC,0x3F,0xFF,0x87,0xFC,0x3F,0xFF,0xC7,0xFC,
    0x3F,0xFF,0xE7,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,
    0x1F,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_button_up_on( char sw_num )
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_cursor( x, y/8 );

    gu_RealTimeImage(32, 32, gu_Button_up_on_data);
}

void gu_Button_up_on2()
{
    gu_cursor(192,8);
    gu_RealTimeImage(32, 32, gu_Button_up_on_data);
}

char gu_Button_down_on_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xF8,
    0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xE7,0xFF,0xFC,
    0x3F,0xE3,0xFF,0xFC,0x3F,0xE1,0xFF,0xFC,0x3F,0xE0,0xFF,0xFC,0x3F,0xE0,0x7F,0xFC,
    0x3F,0xE0,0x3F,0xFC,0x3F,0xE0,0x1F,0xFC,0x3F,0xE0,0x0F,0xFC,0x3F,0xE0,0x07,0xFC,
    0x3F,0xE0,0x07,0xFC,0x3F,0xE0,0x0F,0xFC,0x3F,0xE0,0x1F,0xFC,0x3F,0xE0,0x3F,0xFC,
    0x3F,0xE0,0x7F,0xFC,0x3F,0xE0,0xFF,0xFC,0x3F,0xE1,0xFF,0xFC,0x3F,0xE3,0xFF,0xFC,
    0x3F,0xE7,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,
    0x1F,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_button_down_on(char sw_num)
{
    char    x;
    char    y;

    //SW_NoからSWの座標を求める
    x = ((sw_num - 1) % 8 ) * 32;
    y = ((sw_num - 1) / 8 ) * 32;

    gu_cursor( x, y/8 );

    gu_RealTimeImage(32, 32, gu_Button_down_on_data);
}

void gu_Button_down_on2()
{
    gu_cursor(192,12);
    gu_RealTimeImage(32, 32, gu_Button_down_on_data);
}

char gu_Button_power_on_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x10,0x00,0x00,0x08,
    0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x03,0xF0,0x04,
    0x20,0x0F,0xFC,0x04,0x20,0x1F,0xFE,0x04,0x20,0x3C,0x0F,0x04,0x20,0x38,0x07,0x84,
    0x20,0x00,0x03,0x84,0x20,0x00,0x03,0xC4,0x20,0x00,0x01,0xC4,0x21,0xFF,0x01,0xC4,
    0x21,0xFF,0x01,0xC4,0x20,0x00,0x01,0xC4,0x20,0x00,0x03,0xC4,0x20,0x00,0x03,0x84,
    0x20,0x38,0x07,0x84,0x20,0x3C,0x0F,0x04,0x20,0x1F,0xFE,0x04,0x20,0x0F,0xFC,0x04,
    0x20,0x03,0xF0,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,0x20,0x00,0x00,0x04,
    0x10,0x00,0x00,0x08,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_Button_power_on()
{
    gu_cursor(224,0);
    gu_RealTimeImage(32, 32, gu_Button_power_on_data);
}


char gu_Button_power_off_data[] = {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xF8,
    0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFC,0x0F,0xFC,
    0x3F,0xF0,0x03,0xFC,0x3F,0xE0,0x01,0xFC,0x3F,0xC3,0xF0,0xFC,0x3F,0xC7,0xF8,0x7C,
    0x3F,0xFF,0xFC,0x7C,0x3F,0xFF,0xFC,0x3C,0x3F,0xFF,0xFE,0x3C,0x3C,0x00,0x7E,0x3C,
    0x3C,0x00,0x7E,0x3C,0x3F,0xFF,0xFE,0x3C,0x3F,0xFF,0xFC,0x3C,0x3F,0xFF,0xFC,0x7C,
    0x3F,0xC7,0xF8,0x7C,0x3F,0xC1,0xE0,0xFC,0x3F,0xE0,0x01,0xFC,0x3F,0xF0,0x03,0xFC,
    0x3F,0xFC,0x0F,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,
    0x1F,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

void gu_Button_power_off()
{
    gu_cursor(224,0);
    gu_RealTimeImage(32, 32, gu_Button_power_off_data);
}

/*********************************
    ノリタケ関数
    ここから
**********************************/
//
// Clear screen//
void gu_cls()
{

    i2c.start();
    i2c.write(addr_gu);
    i2c.write(0x0c);
    i2c.stop();

}

void gu_drawButton(int x, int y, int w, int h, const char data[])
{
    h = h >> 3;  // get height in byte
    y = y >> 3;  // get Y location in byte

    gu_cursor(x,y);
    // Realtime Image draw header

    i2c.start();
    i2c.write(addr_gu);
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x66);
    gu_sendOneByte(0x11);
    gu_sendOneByte( w & 0xff);
    gu_sendOneByte( w >> 8);
    gu_sendOneByte( h & 0xff);
    gu_sendOneByte( h >> 8);
    gu_sendOneByte(0x01);

    for(int i = 0; i<w; i++) {
        if(i<8) {                           // 8 dots from left
            gu_sendOneByte(data[i*2]);
            if(h>2) {
                for(int j=0; j<(h-2); j++) {
                    if((data[i*2]&0x01)==0) {
                        gu_sendOneByte(0x00);
                    } else {
                        gu_sendOneByte(0xff);
                    }
                }
            }
            gu_sendOneByte(data[i*2+1]);
        } else if (i > (w-8)) {             // 8 dots from right

            gu_sendOneByte(data[(16+i-w)*2]);
            if(h>2) for(int j=0; j<(h-2); j++) {
                    if((data[(16+i-w)*2]&0x01)==0) {
                        gu_sendOneByte(0x00);
                    } else {
                        gu_sendOneByte(0xff);
                    }
                }
            gu_sendOneByte(data[(16+i-w)*2+1]);

        } else {                              // in the middle
            gu_sendOneByte(data[14]);
            if(h>2) {
                for(int j=0; j<(h-2); j++) {
                    if((data[14]&0x01)==0) {
                        gu_sendOneByte(0x00);
                    } else {
                        gu_sendOneByte(0xff);
                    }
                }
            }
            gu_sendOneByte(data[15]);
        }
    }

    i2c.stop();

}


// ドット単位キャラクタ表示 p37
void gu_print_dot(int x, int y, const char* ptext)
{

    i2c.start();
    i2c.write(addr_gu);
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x64);
    gu_sendOneByte(0x30);
    gu_sendOneByte(x & 0xff);
    gu_sendOneByte(x >> 8);
    gu_sendOneByte(y & 0xff);
    gu_sendOneByte(y >> 8);
    gu_sendOneByte(0x00);

    int i=0;
    int j=0;
    while(*(ptext+i)) {
        if (*(ptext + i++) =='%') {
            j+=2;   //文字列終端”0%"までインクリメント
        }
    }

    gu_sendOneByte(i-j);  //キャラクタデータ長
    gu_print(ptext);       //キャラクタデータ

    i2c.stop();

}

//
// Print test//
void gu_print(const char t[] )
{
    i2c.start();
    i2c.write(addr_gu);

    int i=0;
    int j=0;
    int k=0;
    while(t[i]) {
        if(t[i] != 37) {
            gu_sendOneByte(t[i++]);
        } else {
            i++;
            j=t[i++]-0x30;
            if(j>9) {
                j -= 7;
            }
            if(j>0x10) {
                j -= 0x20;
            }
            k=t[i++]-0x30;
            if(k>9) {
                k -= 7;
            }
            if(k>0x10) {
                k -= 0x20;
            }
            gu_sendOneByte(j*16+k);
        }
    }
    i2c.stop();
}

void gu_RealTimeImage(int w, int h, char data[])
{
    h = h >> 3;  // get height in byte

    i2c.start();
    gu_sendOneByte(addr_gu);
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x66);
    gu_sendOneByte(0x11);
    gu_sendOneByte( w & 0xff);
    gu_sendOneByte( w >> 8);
    gu_sendOneByte( h & 0xff);
    gu_sendOneByte( h >> 8);
    gu_sendOneByte(0x01);
    for( int i=0; i < ( w * h ); i++) {
        gu_sendOneByte( data[i]);
    }
    i2c.stop();
}

// Draw RealTimeBitImage by dot
void gu_RealTimeImage_dot(int x, int y, int w, int h, const char data[])
{
    i2c.start();
    gu_sendOneByte(addr_gu);
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x64);
    gu_sendOneByte(0x21);
    gu_sendOneByte(x & 0xff);
    gu_sendOneByte(x >> 8);
    gu_sendOneByte(y & 0xff);
    gu_sendOneByte(y >> 8);
    gu_sendOneByte(w & 0xff);
    gu_sendOneByte(w >> 8);
    gu_sendOneByte(h & 0xff);
    gu_sendOneByte(h >> 8);
    gu_sendOneByte(0x01);
    for(int i=0; i<( w * ((h + 7)>>3)); i++ ) {
        gu_sendOneByte(data[i]);
    }
    i2c.stop();
}


// Set Font width
void gu_fontWidth(const char fontWidth)
{
    /*
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x67);
    gu_sendOneByte(0x03);
    gu_sendOneByte(fontWidth);
    */

    char accom_gu[5] ;   //gu-DへのI2Cコマンド用配列

    accom_gu[0] = 0x1F;
    accom_gu[1] = 0x28;
    accom_gu[2] = 0x67;
    accom_gu[3] = 0x03;
    accom_gu[4] = fontWidth;

    i2c.write(addr_gu, accom_gu, 5);

}

//
// Move Cursor
// 動作確認完了 2017/6/26
void gu_cursor(int x, int y)
{

    /*
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x24);
    gu_sendOneByte(x%256);
    gu_sendOneByte(x>>8);
    gu_sendOneByte(y%256);
    gu_sendOneByte(y>>8);
    */

    char accom_gu[6] ;   //gu-DへのI2Cコマンド用配列

    accom_gu[0] = 0x1f;
    accom_gu[1] = 0x24;
    accom_gu[2] = x & 0xFF;
    accom_gu[3] = x >> 8;
    accom_gu[4] = y & 0xFF;
    accom_gu[5] = y >> 8;

    i2c.write(addr_gu, accom_gu, 6);

}

// Font Body Size
// 動作確認2017/6/26
void gu_fontsize(const char code)
{
    /*
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x67);
    gu_sendOneByte(0x01);
    gu_sendOneByte(code);
    */
    char accom_gu[5] ;   //gu-DへのI2Cコマンド用配列

    accom_gu[0] = 0x1F;
    accom_gu[1] = 0x28;
    accom_gu[2] = 0x67;
    accom_gu[3] = 0x01;
    accom_gu[4] = code;

    i2c.write(addr_gu, accom_gu, 5);

}


//
// Reverse video font
void gu_fontReverse(int code)
{

    i2c.start();
    gu_sendOneByte(addr_gu);
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x72);
    gu_sendOneByte(code);
    i2c.stop();

}

void gu_touchPara(int x,int y)
{
    i2c.start();
    i2c.write(addr_gu);
    i2c.write(0x1F);
    i2c.write(0x4B);
    i2c.write(0x70);
    i2c.write(x & 0xFF);
    i2c.write(y & 0xFF);
    i2c.stop();
}

// Magnify Font キャラクタ拡大表示
void gu_magnify(int x, int y)
{
    gu_sendOneByte(0x1f);
    gu_sendOneByte(0x28);
    gu_sendOneByte(0x67);
    gu_sendOneByte(0x40);
    gu_sendOneByte(x);
    gu_sendOneByte(y);
}

/*********************************
    ノリタケ関数
    ここまで
**********************************/
//
//Show text
void gu_print1(const char* ptext)
{
    i2c.write(addr_gu, ptext, strlen(ptext));
}
//
//輝度調整
void gu_luminance(const char* cl)
{
    i2c.start();
    i2c.write(addr_gu);
    i2c.write(0x1F);
    i2c.write(0x58);
    i2c.write(*cl & 0xFF);
    i2c.stop();
}
//
//gu_Dクラス用 1バイト送信
void gu_sendOneByte(char data)                                            //arduino->mbed
{
    i2c.write(data);
    //while(digitalRead(gu_MBUSY)==HIGH){} // wait for ready.
    //Serial.write(data);               // send a byte.
}
//
//CF+RF
void gu_CRLF()
{
    char com[2];

    com[0] = 0x0A; //LF
    com[1] = 0x0D; //CR
    i2c.write(addr_gu, com, 2);  //LF+CR
}
//
//リバース指定or解除
void gu_reverse(char x)   //リバース指定or解除
{
    char com[3];

    com[0] = 0x1F;
    com[1] = 0x72;
    com[2] = x & 0xFF; //0x01:指定 0x00:解除
    i2c.write(addr_gu, com, 3);
}
//1byte送信用
void gu_onebyte(char data)
{
    i2c.write(addr_gu, &data, 1);
}
/*****************************************

    SD CARD

*****************************************/
void sd_writetext(const char* ptext)
{

    mkdir("/sd/mydir", 0777);

    FILE *fp = fopen("/sd/mydir/iop.txt", "w");//ディレクトリとファイル名の指定

    if(fp == NULL) {

        gu_fontsize(1);
        gu_cursor(0,2);
        /* ver1.1.3*/
        gu_print1("No SD card");
        //gu_print1("Could not open file for SD card");
        //error("Could not open file for write\n");

    }

    fprintf(fp, ptext);
    fclose(fp);

}



/****************************************

    シーケンサ通信

****************************************/
//一定時間CAL名未送信
void seq_timeout(){
/*
    seq_name[0] = 2;
    seq_name[3] = 3;
*/    
    seq_name[0] = 50;
    seq_name[3] = 51;
}


//CAL名受信
void seq_serialrecive(){
    
    seq_name[0] = pc.getc();
    seq_name[1] = pc.getc();
    seq_name[2] = pc.getc();
    seq_name[3] = pc.getc();
    
    //CAL番号だけ抽出
    reg_num = (seq_name[1] - 0x30) * 10;
    reg_num = reg_num + (seq_name[2] - 0x30);

    //EEPROMへCAL番号を書き込み
    wdata[0] = adrs_calnum[0]; //byte address a15~8
    wdata[1] = adrs_calnum[1]; //byte address a7~a0
    wdata[2] = reg_num;
    Soushin = i2c.write (eeprom_adrs, wdata, 3); //send stop at end default value is false.

}


//測定データ送信
void seq_serialsend(/*int noc*/) //デバック時int nocコメントアウト
{
    char    STX     = 2;
    char    EXT     = 3;
    int     i;
    int     CH[]    = {1,2,3,4};
    int     noc     = 4;
            
    for(i = 0; i <= ( noc - 1); i++){
//PCデバック用    pc.→uart.に変更で装置用へ変更出来る    
        pc.printf("%c" , STX);
        pc.printf("%d" , CH[i]);
        pc.printf("%c" , ',');
        pc.printf("%d" , seq_name[0]);
        pc.printf("%c" , ',');
        pc.printf("%d" , seq_name[3]);
        pc.printf("%c" , ',');
        pc.printf("%d" , reg_num);
        pc.printf("%c" , ',');
        pc.printf("%s\n" , calinfo.name);
        pc.printf("%c" , ',');
        
        //アンテナ抵抗値
        if(R[i] < res_vref && R[0] >= 0){
            pc.printf("%d" , R[i]);    
            }
        else{
            pc.printf("%s" , "OL");
            }
                
        pc.printf("%c" , ',');      
        pc.printf("%f" , fdata[i][0]);   //Iop
        pc.printf("%c" , ',');
        pc.printf("%f" , fdata[i][1]);   //Idd
        pc.printf("%c" , ',');
        pc.printf("%f" , fdata[i][2]);   //Voc
        pc.printf("%c" , ',');
        pc.printf("%f" , vocp[i]);
        pc.printf("%c" , ',');
        
        if(err_f == 0){                       //void hanteiのエラーフラグを流用
            pc.printf("%s" , "PASS");
            }
        else{
            pc.printf("%s" , "FAIL");
            }
            
        pc.printf("%c" , ',');
        pc.printf("%d" , cat);                
        pc.printf("%c\n" , EXT);
        }//for
    
}