2016年6月26日日曜日

NucleoシーケンサーとPSoC4 DCOとDCAの結合テスト(UIなし)

NucleoシーケンサーのUIを省いてDCO->DCAのテスト

配線図


MCP4922+NJM13700のDCAのエンベロープ波形をコントロールするPOTはつないでいる。

 Level | Duration | Decay | Sustain

Nucleoシーケンサー:
https://developer.mbed.org/users/ryood/code/SpiSequenceSender_Test/

PSoC4 DCO:
https://github.com/ryood/PSoC4_DCO/tree/master/PSoC/PSoC4_DCO_for_NucleoF401RE_Interrupt_Test.cydsn

SpiSequenceSender_Test
main.cpp

#include "mbed.h"
#include "rtos.h"

#define UART_TRACE  (0)
#include "SpiSequenceSender.h"
#include "EnvelopeGenerator.h"
#include "SpiAmpController.h"

#define SEQUENCE_N  (16)
#define SPI_RATE    (8000000)

const int samplingPeriod = 1;   // ms
const int bpm = 120;
const int envelopeLength = (60 * 1000 / (bpm * 4)) / samplingPeriod;

AnalogIn levelIn(A0);
AnalogIn durationIn(A1);
AnalogIn decayIn(A2);
AnalogIn sustainIn(A3);

SPI spiMaster(SPI_MOSI, SPI_MISO, SPI_SCK);

Sequence sequence[SEQUENCE_N];
SpiSequenceSender sequenceSender(&spiMaster, D9, sequence, SEQUENCE_N, samplingPeriod, bpm);

Envelope envelope(4095, envelopeLength, envelopeLength*3/4, envelopeLength/2, 2047);
EnvelopeGenerator envelopeGenerator;
SpiAmpController ampController(&spiMaster, D8, D7);


class TestClass {
public:
    void callbackFunction(int ticks)
    {
        if (ticks == 0) {
            envelopeGenerator.init(envelope);
        }
        uint16_t level = envelopeGenerator.getModLevel();
        //printf("m,%d\r\n", level);
        ampController.outDca(level);
        envelopeGenerator.update();
    }
} testClass;

void callbackFunction(int ticks)
{
    if (ticks == 0) {
        envelopeGenerator.init(envelope);
    }
    uint16_t level = envelopeGenerator.getModLevel();
    //printf("g,%d\r\n", level);
    ampController.outDca(level);
    envelopeGenerator.update();
}

int main()
{
    spiMaster.format(8, 0);
    spiMaster.frequency(SPI_RATE);
    
    // Test SequencerSender Run
    //
    sequenceSender.setBpm(bpm);
    for (int i = 0; i < SEQUENCE_N; i++) {
        Sequence& seq = sequenceSender.getSequences()[i];
        seq.setPitch(i);
        seq.setOctave(-1);
        seq.tie = true;
    }

    sequence[3].setOctave(0);
    sequence[7].setOctave(0);
    sequence[11].setOctave(0);
    sequence[15].setOctave(0);
    
    envelopeGenerator.init(envelope);
    
    sequenceSender.attachUpdate(&testClass, &TestClass::callbackFunction);
    //sequenceSender.attachUpdate(&callbackFunction);
    sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SAW);
    sequenceSender.run(0);
    
    for (;;) {
        /*
        sequenceSender.setPulseWidth(sequenceSender.getPulseWidth() + 4);
        Thread::wait(500);
        sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SAW);
        Thread::wait(500);
        sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SQUARE);
        */
        envelope.setLevel(levelIn * 4095);
        envelope.setDuration(durationIn * envelopeLength);
        envelope.setDecay(decayIn * envelopeLength);
        envelope.setSustain(sustainIn * 4095);
    }
}

プログラムはCallbackのテストも兼ねているのでTestClass::callbackFunction(int ticks)とcallbackFunction(int ticks)を定義しているが、呼び出しているのはcallbackFunction(int ticks) TestClass::callbackFunction(int ticks)。

入出力波形



ch1:DCA出力波形 ch2:PSoC4 DCO出力波形

PSoC4 DCOの出力を100mV(p-p)以下にしているので、ノイズ(おそらくSPI信号)がかなり重畳している。


ch1:DCA出力波形 ch2:MCP4922の出力波形(エンベロープ)

エンベロープを変化させたようすをYoutubeにあげた。


メモ:


DCOの出力波形が0V~+100mV程度になっているのを-50mV~0V~+50mVにしたほうがいいか?
→AC結合すればなんとかなる(@@?

シーケンスのnoteOn/Offは未実装。DCOではなくDCAで処理する。

エンベロープのパラメータをいじるPOTx4はNucleoのArduino HeadersではなくMorpho Headersに繋げるようにする?