Tetsuki Fukuda / Mbed 2 deprecated Red_StandAlone_Switch_demo

Dependencies:   mbed

main.cpp

Committer:
Tetsuki
Date:
2021-03-16
Revision:
0:388a5969e586

File content as of revision 0:388a5969e586:

/**************************
For high-voltage switching circuit test
2016 Sep. 2-
Hiroyuki Kajimoto
***************************
2020/08/02
編集者:福田哲生
変更点:
以前のStandAlone_demoでは常にひげのジョリジョリ感を
570Vで出し続けるプログラムであった。

今回は3Dプリンタによるハードケースおよび、
モバイルバッテリーと昇圧ケーブルによる
ポータブル化がすすめられたため
ハードケースに付属させたスイッチによって
刺激を変更できるようにした。

ハードケースをつけるとmbed本体LEDは見えないが
電源スイッチオン(初期状態)で無灯火、刺激なし
の状態から切り替えスイッチを1回押すごとに
LED1点灯、sine波
LED2点灯、ひげジョリジョリ
LED3点灯、羊角ゴツゴツ
LED4点灯、羊体モフモフ
LED1,2点灯、犬サラモフ
LED1,3点灯、炭酸シュワシュワ
と、LED表示および刺激が遷移していく。

なお赤い基板にあるp16の部分と3.3V,GNDをスイッチに配線し
p16がHighになると切り換わるようにした。
チャタリング対策に200msの待機時間を設けた。

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

#include "mbed.h"
#include <stdio.h>
#include <stdlib.h>

DigitalOut SN74LV595_DIN(p14);
DigitalOut SN74LV595_RCLK(p13);
DigitalOut SN74LV595_CLR(p12);
DigitalOut SN74LV595_CLK(p11);
DigitalIn  SN74LV595_DOUT(p10); //Shift register output, so normally it is not connected.

DigitalIn  Switch(p16);//スイッチ用ピン 

//DAAD
SPI spiDAAD(p5, p6, p7);     // mosi(master output slave input, miso(not connected), clock signal
DigitalOut DA_sync(p8);        //chip select for AD5452
DigitalOut AD_cs(p9);        //chip select for AD7276

//Other I/O
BusOut myleds(LED1, LED2, LED3, LED4);

//LED1からLED4をled1からled4に割り当てる。
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);


// stimulation mode
#define DA_TEST 0xFA //sinusoidal wave mode to test DA
#define MIN_TIME_DIFF 200//チャタリング用待機時間

const int ELECTRODE_NUM = 16;
short stim_pattern[ELECTRODE_NUM] = { 0 };
short impedance[ELECTRODE_NUM] = { 0 };

Timer timer;
Timer mytimer;

bool AccessDeny = false;

int i;
int Freq = 100;//正弦波、ひげの周波数
int trigger = 0;//三角波用トリガー
double LowFreq = 0;
int TIME = 0;//炭酸用

int swflag = 0;//スイッチ用フラグ


/******************************************************************************/
/*
 SN74LV595 Data Transfer
 2 bits are required for 1 electrode.
 00 OPEN
 10 GND
 01 HIGH
 11 SHORT
 */
/******************************************************************************/
void SN74LV595FastScan(int usWhichPin)
{
    int ii, pin;
    static int pos;

    SN74LV595_RCLK = 0;
    if (usWhichPin == 0) { //set 01(High)
        SN74LV595_DIN = 0;
        SN74LV595_CLK = 1;
        SN74LV595_CLK = 0;
        SN74LV595_DIN = 1;
        SN74LV595_CLK = 1;
        SN74LV595_CLK = 0;
        pos = 0;
    }
    else { 
        pin = usWhichPin - pos;
        for (ii = 0; ii < pin; ii++) {//set 10 (GND)
            SN74LV595_DIN = 1;
            SN74LV595_CLK = 1;
            SN74LV595_CLK = 0;
            SN74LV595_DIN = 0;
            SN74LV595_CLK = 1;
            SN74LV595_CLK = 0;
        }
        pos = usWhichPin;
    }
    //Load S/R
    SN74LV595_RCLK = 1;
    SN74LV595_RCLK = 0;
}

/******************************************************************************/
/*
 SN74LV595 init & Clear
 */
/******************************************************************************/
void SN74LV595Clear()
{
    SN74LV595_CLR = 0;
    SN74LV595_RCLK  = 0;
    SN74LV595_CLK = 0;
    SN74LV595_CLK = 1;
    SN74LV595_CLK = 0;
    SN74LV595_CLR = 1;
}

void SN74LV595Init(int TotalPin)
{
    int ii;

    SN74LV595_CLR = 1;
    SN74LV595_CLK = 0;
    SN74LV595_RCLK = 0;
    for (ii = 0; ii < TotalPin; ii++) {
        SN74LV595_DIN = 1;
        SN74LV595_CLK = 1;
        SN74LV595_CLK = 0;
        SN74LV595_DIN = 0;
        SN74LV595_CLK = 1;
        SN74LV595_CLK = 0;
    }
    //Load S/R
    SN74LV595_RCLK = 1;
    SN74LV595_RCLK = 0;
}


/******************************************************************************/
/*
DA&AD at the same time, using the same SPI clock.
DA output by AD5452(SPI)
AD input by AD7276(SPI)
 */
/******************************************************************************/

short DAAD(short DA)
{
    short AD;

        //enable
    DA_sync = 0;
    AD_cs = 0;
    //simultaneous DA and AD
    AD = spiDAAD.write(DA << 2);
    //disable
    DA_sync = 1;
    AD_cs = 1;

    return AD >> 2;//bottom 2bits are unnecessary
}

void DAADinit()
{
    //Setup SPI, 16bit, falling edge, 48MHz clock
    spiDAAD.format(16, 2);
    spiDAAD.frequency(48000000);
}


int main()
{
    double t=0.0;
    short AD;
    int Randnum[10] = {400,600,200,500,700,200,600,300,600,500};//待機時間の配列
    int timediff = 0;
    Switch.mode(PullDown);

    DAADinit();
    SN74LV595Init(ELECTRODE_NUM);
    timer.start();
    mytimer.start();

    while (1) {
             
            if(Switch.read() == 1){
                 timediff = mytimer.read_ms();
                 if(timediff > MIN_TIME_DIFF) {
                      swflag = swflag + 1;
                 }
                 mytimer.reset();
            }
            if(swflag == 7){
                 swflag = 1;
            }
            if (swflag == 0){
                myleds = 0; 
            }   
            if (swflag == 1) { //sin波を出力します
                t = (double)timer.read_us() * 0.000001;
                AD = DAAD((short)285 + (285 * (sin(2.0 * 3.1415926 * Freq * t)))); //SinWave
                led1 = 1;
                led2 = 0;
                led3 = 0;
                led4 = 0;
            }
            else if (swflag == 2) { //ひげのジョリジョリ(矩形波)を出力します
                t = (double)timer.read_us() * 0.000001;
                for(i =0; i<10; i++){
                    double Freqdevided1 = 200 / Freq;//出力時間
                    double Freqdevided2 = Randnum[i] / Freq;//待機時間は配列でランダム(?)化
                    double Freqint1 = floor(Freqdevided1);//整数化
                    double Freqint2 = floor(Freqdevided2);
                    AD = DAAD(570);
                    wait_ms(Freqint1);
                    DAAD(0);
                    wait_ms(Freqint2);
                    AD = DAAD(400);
                    wait_ms(Freqint1);
                    DAAD(0);
                    wait_ms(Freqint2);
                    led1 = 0;
                    led2 = 1;
                    led3 = 0;
                    led4 = 0;
                }
            }
            else if (swflag == 3) {//羊の角のゴツゴツ感(三角波)を出力します
                for(int j = 0; j<10; j++){
                    t = (double)timer.read_us() * 0.000001;
                    double sigma = 0;//フーリエ級数のシグマ
                    for(i = 1; i < 4; i++){
                        sigma += sin(i * 3.1415926 / 2) * sin(i * t * 6.29 * 40)/(i * i);//三角波をフーリエ級数変換したやつ
                        }
                    AD = DAAD((short) 300 + (8 * 300 * sigma / (3.1415926 * 3.1415926)));
                    if(AD < 100 && trigger == 1){//トリガーが1だといくらか待ちます
                        wait_ms(Randnum[j] / 20);
                        trigger = 0;
                    }
                    if(AD > 100 && trigger == 0){//トリガーが0の時は普通に三角波を出力してトリガーを1に変更
                        trigger = 1;
                        }
                }
                    led1 = 0;
                    led2 = 0;
                    led3 = 1;
                    led4 = 0;
        }
       else if (swflag == 4){//羊の体のモフモフ感(エンベロープ)を出力します 
           t = (double)timer.read_us() * 0.000001;
           LowFreq = (short)(144 * (1.0 + sin(2.0 * 3.1415926 * 7 * t))); //低周波の方
           AD = DAAD((short)(LowFreq * ((1.0 + sin(2.0 * 3.1415926 * 200 * (t+5000000))))));
                    led1 = 0;
                    led2 = 0;
                    led3 = 0;
                    led4 = 1;
        }
        else if (swflag == 5) {//犬の体のサラサラ感(エンベロープ)を出力します。
        t = (double)timer.read_us() * 0.000001;
           LowFreq = (short)(200 * (1.0 + sin(2.0 * 3.1415926 * 80 * t))); //低周波の方
           AD = DAAD((short)(LowFreq / 2 * ((1.0 + sin(2.0 * 3.1415926 * 320 * (t+5000000))) + (1.0 + sin(2.0 * 3.1415926 * 240 * (t+5000000))))));//低周波の出力を振幅にして合成波を出力します
                    led1 = 1;
                    led2 = 1;
                    led3 = 0;
                    led4 = 0;
        }
        else if (swflag == 6) {//炭酸のシュワシュワ感を出力します。
                t = (double)timer.read_us() * 0.000001;
                AD = DAAD((short)(570 * (1.0 + sin(2.0 * 3.1415926 * Freq * t))));
                TIME = TIME +1;
                if(TIME>1000){
                    double Freqdevided1 = 100*(rand()%3)/ Freq;//出力時間はランダム化
                    double Freqdevided2 = 10*(rand()%10);//待機時間もランダム化
                    double Freqint1 = floor(Freqdevided1);//整数化
                    double Freqint2 = floor(Freqdevided2);
                    AD = DAAD(100*(3+rand()%3));
                    wait_ms(Freqint1);
                    AD = DAAD(0);
                   wait_ms(Freqint2);
                }
                    led1 = 1;
                    led2 = 0;
                    led3 = 1;
                    led4 = 0;
        }  
    }
}