が究極のナチュラルコンピューティングかもしれない。導体に拘らなければ新しい世界が拓けるだろう。
2020年10月3日 近い理論を知りました。光で演算する方法です。
https://doi.org/10.1364/OE.399495
なので今後も「The Optical Society」を注目していきます。
ニュース
が究極のナチュラルコンピューティングかもしれない。導体に拘らなければ新しい世界が拓けるだろう。
2020年10月3日 近い理論を知りました。光で演算する方法です。
https://doi.org/10.1364/OE.399495
なので今後も「The Optical Society」を注目していきます。
74HC164Nでシリアルパラレル変換した後74LS273PCでその値を保持できるか実験してみました。同時にソフトウェアを改良しキーボードからバイト単位に信号を送出できるようにしました。
キーボードで16進数を1バイト分入力しEnterを押すとその値に応じてLEDが点灯しています。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") constexpr auto SAMPLING = 192000; constexpr auto CHANNEL = 2; constexpr auto BITSPERSAMPLE = 16; void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = SAMPLING / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } BOOLEAN isON(unsigned char data, size_t bit, size_t i) { size_t bit9 = bit * 9; size_t bit8 = bit * 8; size_t bit7 = bit * 7; size_t bit6 = bit * 6; size_t bit5 = bit * 5; size_t bit4 = bit * 4; size_t bit3 = bit * 3; size_t bit2 = bit * 2; if (((data & 0x80) == 0x80) && 0 <= (i % (bit9)) && (i % (bit9)) < (bit)) { return true; } if (((data & 0x40) == 0x40) && (bit) <= (i % (bit9)) && (i % (bit9)) < (bit2)) { return true; } if (((data & 0x20) == 0x20) && (bit2) <= (i % (bit9)) && (i % (bit9)) < (bit3)) { return true; } if (((data & 0x10) == 0x10) && (bit3) <= (i % (bit9)) && (i % (bit9)) < (bit4)) { return true; } if (((data & 0x08) == 0x08) && (bit4) <= (i % (bit9)) && (i % (bit9)) < (bit5)) { return true; } if (((data & 0x04) == 0x04) && (bit5) <= (i % (bit9)) && (i % (bit9)) < (bit6)) { return true; } if (((data & 0x02) == 0x02) && (bit6) <= (i % (bit9)) && (i % (bit9)) < (bit7)) { return true; } if (((data & 0x01) == 0x01) && (bit7) <= (i % (bit9)) && (i % (bit9)) < (bit8)) { return true; } return false; } static LPWORD lpWave; static WAVEHDR whdr; void soundOut(HWAVEOUT hWaveOut, unsigned char data) { LPWORD lpData; LPWORD lpWave1; LPWORD lpWave2; LPWORD lpWave3; LPWORD lpWave4; // 最初と最後の1sは出力しないので3以上とする DWORD terms = 3; size_t i, j, k, start, end; size_t frequency = 9; size_t wavelength = SAMPLING / frequency; size_t dataLength = (size_t)CHANNEL * (size_t)SAMPLING * terms; lpWave = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave1 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave2 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave3 = (LPWORD)calloc(sizeof(WORD), dataLength); lpWave4 = (LPWORD)calloc(sizeof(WORD), dataLength); end = SAMPLING * CHANNEL; WORD amplitude = 32767 / 4; for (i = 0; i < end; i++) { lpWave[i] = 0; lpWave1[i] = 0; lpWave2[i] = 0; lpWave3[i] = 0; lpWave4[i] = 0; } size_t bit = CHANNEL * SAMPLING / frequency; // 最初の1sは出力しない start = SAMPLING * CHANNEL; end = (size_t)CHANNEL * (size_t)SAMPLING * (size_t)terms; // 最後の1sは出力しない end -= SAMPLING * CHANNEL; size_t valWavelength; size_t valFrequency; /* チャンネル1 ********************************/ lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, SAMPLING, amplitude); for (i = start, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); /* チャンネル2 ********************************/ // クロック valFrequency = 3200; valWavelength = SAMPLING / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, SAMPLING, amplitude); for (i = start + 1, j = 0, k = 0; i < end; i += 2, ++j, ++k) { if (k < SAMPLING / frequency / 2) { lpWave1[i] = lpData[j]; } if (j >= valWavelength) { j = 0; } if (k >= SAMPLING / frequency) { k = 0; } } free(lpData); // シリアルデータ1 valFrequency = 8000; valWavelength = SAMPLING / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < end; i += 2, ++j) { lpWave2[start + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } free(lpData); // シリアルデータ2 valFrequency = 11300; valWavelength = SAMPLING / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, SAMPLING, amplitude); for (i = 1, j = 0; i < end; i += 2, ++j) { lpWave3[start + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } for (i = 1, j = 0; i < end; i += 2, j += 2) { if (j >= bit * 9) { j = 0; } if (isON(data, bit, i)) { lpWave3[start + i] = 0; } } free(lpData); // リセット valFrequency = 17000; valWavelength = SAMPLING / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, SAMPLING, amplitude); for (i = 1; i < end; i += 2, ++j) { lpWave4[start + i] = 0; } for (i = 1, j = 0; i < (end - bit * 9); i += 2, ++j) { if ((i % (bit * 9)) < bit) { lpWave4[start + i - bit] = lpData[j]; } if (j >= valWavelength) { j = 0; } } free(lpData); // チャンネル2に合成 for (i = 1; i < end; i += 2) { lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i]; } // サウンド出力 whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = SAMPLING * (CHANNEL * BITSPERSAMPLE / 8) * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); } int main() { WAVEFORMATEX wfe; HWAVEOUT hWaveOut; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = CHANNEL; wfe.wBitsPerSample = BITSPERSAMPLE; wfe.nBlockAlign = CHANNEL * BITSPERSAMPLE / 8; wfe.nSamplesPerSec = SAMPLING; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); char str[128]; do { std::cout << "2桁の16進コードを入力しEnterを押して下さい。(00 ~ FF)" << std::endl; std::cout << "Ctrl+Zを入力しEnterを入力すると終了します。" << std::endl; std::cin >> str; // 入力された文字列をデータに変換 unsigned char data = (unsigned char)strtol(str, NULL, 16); // Ctrl+Zで終了 if (std::cin.eof()) { break; } // データをサウンド出力する soundOut(hWaveOut, data); } while (true); waveOutClose(hWaveOut); }
ここまででPCのサウンド出力を使ってデジタル素子を制御出来ることが解りました。
ChatGPTに聞いてみた。
User
レギュレーターの7905は何ですか。
ChatGPT
7905は、負の電源電圧を出力する固定型線形レギュレーターの1つで、5Vの出力を提供します。このレギュレーターは、電源電圧が入力されると、出力電圧を一定に保ち、負荷の変化に対しても安定した出力を提供することができます。
7905は、TO-220パッケージで提供され、3ピンのパッケージングを採用しています。このレギュレーターには、入力ピン、共通接地ピン、出力ピンがあります。また、一部の製品には、過熱保護回路も内蔵されています。
7905は、入力電圧が6.5Vから35Vの範囲で動作し、出力電流は最大1Aまで供給することができます。また、このレギュレーターは、定電圧により多くの電子回路で使用されており、オーディオ機器、電子機器、制御機器、産業用途などに広く使用されています。
ChatGPTに聞いてみた。
User
SN74HC04Nは何ですか。
ChatGPT
SN74HC04Nは、ヘキサインバータ(Hex Inverter)IC(集積回路)の1つです。このICは、6つのインバータを持っており、入力信号を反転させ、出力信号を生成することができます。また、このICは、高速で動作し、低消費電力であるため、多くのデジタルシステムに適しています。
SN74HC04Nは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、6つのインバータがあり、それぞれのインバータには、入力ピンと出力ピンがあります。
SN74HC04Nは、高速な信号反転や駆動、多くのデジタルシステムでの信号調整などのアプリケーションに適しています。また、このICは、パルスジェネレーション、クロックドライバ、バッファリングなどのために、広く使用されています。
74HC164Nでシリアルパラレル変換ができるとはByteデータを送り込めるということになります。ソフトウェアを改良しByte単位にデータを送れるか実験してみました。
ピークが15回出ています。これが74HC164Nにリセット信号を送っているところで、その手前が1バイトのビットデータとなります。74HC164NはNOT出力ですので信号が立っているところが0、立っていないところが1と解釈してください。1、3、5、7と増えていくのが波形からわかります。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } BOOLEAN isON(unsigned char data, size_t bit, size_t i) { size_t bit9 = bit * 9; size_t bit8 = bit * 8; size_t bit7 = bit * 7; size_t bit6 = bit * 6; size_t bit5 = bit * 5; size_t bit4 = bit * 4; size_t bit3 = bit * 3; size_t bit2 = bit * 2; if (((data & 0x80) == 0x80) && 0 <= (i % (bit9)) && (i % (bit9)) < (bit)) { return true; } if (((data & 0x40) == 0x40) && (bit) <= (i % (bit9)) && (i % (bit9)) < (bit2)) { return true; } if (((data & 0x20) == 0x20) && (bit2) <= (i % (bit9)) && (i % (bit9)) < (bit3)) { return true; } if (((data & 0x10) == 0x10) && (bit3) <= (i % (bit9)) && (i % (bit9)) < (bit4)) { return true; } if (((data & 0x08) == 0x08) && (bit4) <= (i % (bit9)) && (i % (bit9)) < (bit5)) { return true; } if (((data & 0x04) == 0x04) && (bit5) <= (i % (bit9)) && (i % (bit9)) < (bit6)) { return true; } if (((data & 0x02) == 0x02) && (bit6) <= (i % (bit9)) && (i % (bit9)) < (bit7)) { return true; } if (((data & 0x01) == 0x01) && (bit7) <= (i % (bit9)) && (i % (bit9)) < (bit8)) { return true; } return false; } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpWave1; static LPWORD lpWave2; static LPWORD lpWave3; static LPWORD lpWave4; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする DWORD terms = 17; size_t i, j, k, start, end; size_t frequency = 9; size_t sampling = 192000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave1 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave2 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave3 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave4 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels; WORD amplitude = 32767/4; for (i = 0; i < end; i++) { lpWave[i] = 0; lpWave1[i] = 0; lpWave2[i] = 0; lpWave3[i] = 0; lpWave4[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels; size_t valWavelength; size_t valFrequency; size_t bit = wfe.nChannels * sampling / frequency; /* チャンネル1 ********************************/ lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); /* チャンネル2 ********************************/ // クロック valFrequency = 3200; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = start + 1, j = 0, k = 0; i < end; i += 2, ++j, ++k) { if (k < sampling / frequency / 2) { lpWave1[i] = lpData[j]; } if (j >= valWavelength) { j = 0; } if (k >= sampling / frequency) { k = 0; } } free(lpData); const unsigned char dataList[] = { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; size_t dataLen = sizeof(dataList) / sizeof(*dataList); unsigned char data = 0x00; // シリアルデータ1 valFrequency = 8000; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 1, j = 0; i < end; i += 2, ++j) { lpWave2[start + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } free(lpData); // シリアルデータ2 valFrequency = 11300; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 1, j = 0; i < end; i += 2, ++j) { lpWave3[start + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } for (i = 1, j = 0, k = 0; i < end; i += 2, j += 2) { data = dataList[k]; if (j >= bit * 9) { j = 0; ++k; } if (k >= dataLen) { k = 0; } if (isON(data, bit, i)) { lpWave3[start + i] = 0; } } free(lpData); // リセット valFrequency = 17000; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 1; i < end; i += 2, ++j) { lpWave4[start + i] = 0; } for (i = 1, j = 0; i < end; i += 2, ++j) { if ((i % (bit * 9)) < bit) { lpWave4[start + i - bit] = lpData[j]; } if (j >= valWavelength) { j = 0; } } free(lpData); // チャンネル2に合成 for (i = 1; i < end; i += 2) { lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i]; } // サウンド出力 whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
アナログ信号をデジタル信号のようにON/OFFしてLEDを明滅させたとしても信号自体はアナログであるためそのままでデジタル素子を制御できるわけではありません。
そこでデジタル素子で扱える信号にするため74HC14APを使いhigh:+5V, low:0Vの本物のデジタル信号にできるか実験してみました。
4chフィルタから出た信号を検波(復調)後74HC14APで波形を整え74HC164Nでシリアルパラレル変換しました。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpWave1; static LPWORD lpWave2; static LPWORD lpWave3; static LPWORD lpWave4; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 402; size_t i, j, k, start, end, cycle; size_t frequency = 16; size_t sampling = 192000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave1 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave2 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave3 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); lpWave4 = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767/4; for (i = 0; i < end; i++) { lpWave[i] = 0; lpWave1[i] = 0; lpWave2[i] = 0; lpWave3[i] = 0; lpWave4[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; cycle = frequency; /* チャンネル1 ********************************/ lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); /* チャンネル2 ********************************/ // クロック valFrequency = 3200; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = start + 1, j = 0, k = 0; i < end; i += 2, ++j, ++k) { if (k < sampling / cycle / 2) { lpWave1[i] = lpData[j]; } if (j >= valWavelength) { j = 0; } if (k >= sampling / cycle) { k = 0; } } free(lpData); // シリアルデータ1 valFrequency = 8000; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 0, j = 0; i < end; i += 2, ++j) { lpWave2[1 + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } free(lpData); for (i = 0,j = 0, k = 0; i < end- (wfe.nChannels * sampling / cycle * 2); i += 2, ++k) { if (j < 8) { lpWave2[start + 1 + i + (wfe.nChannels * sampling / cycle * 2)] = 0; } if (k >= sampling / cycle) { k = 0; ++j; } if (j >= 8) { j = 0; } } // シリアルデータ2 valFrequency = 11300; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 0, j = 0; i < end; i += 2, ++j) { lpWave3[1 + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } free(lpData); for (i = 0, j = 0, k = 0; i < end - (wfe.nChannels * sampling / cycle * 2); i += 2, ++k) { if (j < 3) { lpWave3[start + 1 + i + (wfe.nChannels * sampling / cycle * 2)] = 0; } if (k >= sampling / cycle) { k = 0; ++j; } if (j >= 8) { j = 0; } } // リセット valFrequency = 17000; valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); for (i = 0, j = 0; i < end; i += 2, ++j) { lpWave4[start + 1 + i] = lpData[j]; if (j >= valWavelength) { j = 0; } } free(lpData); for (i = 0; i < end; i += 2) { if (wfe.nChannels * sampling / cycle * 1 < i) { lpWave4[start + 1 + i] = 0; } } // チャンネル2に合成 for (i = 1, j = 0; i < end; i += 2) { lpWave[i] = lpWave1[i] + lpWave2[i] + lpWave3[i] + lpWave4[i]; } // サウンド出力 whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
デジタルのようなアナログ信号が綺麗な矩形波に整えられているいることがわかる波形です。
ソフトウェアでPCのサウンド出力にクロック、リセット、データの3チャンネル混合信号を送出しフィルター検波ー波形整形ーシリアルパラレル変換するところまでできるようになりました。
PCのサウンド出力を多チャンネル化し複数の信号を扱える装置をなぜ作っているかの理由ですが、8085を動かすためにはどうしてもROMが必要で、それにはROMライタがなければ何もできません。
ROMライタを手に入れれば何のことも無いのですが、勉強がてら作成することにしました。
マイコンボードをUSBに繋いでROMに必要な信号を送る方法が定石のようですが8085の時代にUSBや今のシングルボードコンピュータがあったわけではないのでオペアンプとジャンクに近い部品で作成しようとしています。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 12; size_t i, j, k, start, end; size_t frequency = 400; size_t sampling = 192000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767/4; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); valFrequency = 3200; valWavelength = sampling / valFrequency; for (i = start + 1, j = 0, k = 0; i < end; i += 2) { if (j == 0) { lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } if (sampling/4 * 0 <= k && k < sampling/4 * 1) { lpWave[i] = lpData[j]; } ++j; ++k; if (j >= valWavelength) { j = 0; free(lpData); } if (k >= sampling) { k = 0; } } valFrequency = 8000; valWavelength = sampling / valFrequency; for (i = start + 1, j = 0, k = 0; i < end; i += 2) { if (j == 0) { lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } if (sampling/4 * 1 <= k && k < sampling/4 * 2) { lpWave[i] += lpData[j]; } ++j; ++k; if (j >= valWavelength) { j = 0; free(lpData); } if (k >= sampling) { k = 0; } } valFrequency = 11300; valWavelength = sampling / valFrequency; for (i = start + 1, j = 0, k = 0; i < end; i += 2) { if (j == 0) { lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } if (sampling/4 * 2 <= k && k < sampling/4 * 3) { lpWave[i] += lpData[j]; } ++j; ++k; if (j >= valWavelength) { j = 0; free(lpData); } if (k >= sampling) { k = 0; } } valFrequency = 17000; valWavelength = sampling / valFrequency; for (i = start + 1, j = 0, k = 0; i < end; i += 2) { if (j == 0) { lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } if (sampling/4 * 3 <= k && k < sampling/4 * 4) { lpWave[i] += lpData[j]; } ++j; ++k; if (j >= valWavelength) { j = 0; free(lpData); } if (k >= sampling) { k = 0; } } whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
4つの異なる周波数の信号を混合しPCからサウンド出力します。それぞれ別に信号が出ている時はhigh、出ていない時はlowとすれば1つのアナログ信号を4つのデジタル信号として解釈できるはずです。
741Cを2個1組にして4組のフィルタで分離しそれぞれをまた741Cで増幅後、ダイオードで検波しています。各信号を復調し信号を取り出す仕組みです。
PCからLEDを順に点灯する信号を出してみました。意図通りそれぞれ別の周波数のhighとlowの信号が4つに分離されています。
振幅偏移変調による多重化通信装置の完成です。
クワッド低ノイズ演算増幅回路
ChatGPTに聞いてみた。
User
uPC458Cは何ですか。
ChatGPT
uPC458Cは、オペアンプ(Operational Amplifier)IC(集積回路)の1つです。このICは、高利得、高入力インピーダンス、高CMRR(共通モード抑制比)、低歪みなどの特性を持っており、アナログ回路における信号増幅やフィルタリング、波形整形などに使用されます。
uPC458Cは、デュアルインラインパッケージ(DIP)で提供され、8ピンのパッケージングを採用しています。このICには、2つのオペアンプがあり、それぞれのオペアンプには、非反転入力ピン、反転入力ピン、出力ピン、電源ピンがあります。
uPC458Cは、高速な信号増幅やフィルタリング、低歪みなどの特性を持っており、音響機器、計測機器、通信機器、制御機器などのアプリケーションに広く使用されています。
オペアンプ二段増幅型バンドパスフィルタが思いのほか上手く出来たので4個並べてみました。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 7; size_t i, j, start, end; size_t frequency = 400; size_t sampling = 192000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); for (i = start + 1, j = 0; i < end; i += 2) { if (j == 1) { valFrequency = frequency + ((i - start) * (20000.0 - frequency)) / (sampling * wfe.nChannels * (terms - 2)); valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } lpWave[i] = lpData[j]; ++j; if (j >= valWavelength) { j = 0; free(lpData); } } whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
可聴範囲を4分割し多チャンネル化できました。普通のPCであればステレオサウンド出力は付いているので左右に適用すれば8チャンネル、フィルタをもっと丁寧に作ればそれ以上も可能と思います。
文庫本として読んでみましたが理解できませんでした。前半が論文で後半が解説になっており一般の人でも解る構成だそうですが、光速が不変であることぐらいしか読み取ることができませんでした。これで終わってはもったいないので数式を解るところまで勉強してみます。
運動学の部
$$t_B-t_A=t’_A-t_B$$
$$\frac{2\overline{AB}}{t’_A-t_A}=c$$
$$t_B-t_A=\frac{r_{AB}}{c-v’}$$
$$t’_A-t_B=\frac{r_{AB}}{c+v’}$$
$$\frac{1}{2}(\tau_0+\tau_2)=\tau_1$$
$$\frac{1}{2}\left\{\tau(0,0,0,t)+\\\tau\left(0,0,0,t+\frac{l’}{c-v}+\frac{l’}{c+v}\right)\right\}\\=\tau\left(l’,0,0,t+\frac{l’}{c-v}\right).$$
$$\frac{\partial \tau}{\partial x’}+\frac{v}{c^2-v^2}\frac{\partial \tau}{\partial t}=0$$
$$\frac{\partial \tau}{\partial y}=0, \frac{\partial \tau}{\partial z}=0$$
$$\tau=a\left(t-\frac{v}{c^2-v^2}x’\right)$$
$$\xi=c\tau$$
$$\xi=ac\left(t-\frac{v}{c^2-v^2}x’\right)$$
$$\frac{x’}{c-v}=t.$$
$$\xi=a\frac{c^2}{c^2-v^2}x’.$$
$$\eta=c\tau=ac\left(t-\frac{v}{c^2-v^2}x’\right).$$
$$\frac{y}{\sqrt{c^2-v^2}}=t,\space x’=0$$
$$\eta=a\frac{c}{\sqrt{c^2-v^2}}y.$$
$$\xi=a\frac{c}{\sqrt{c^2-v^2}}z.$$
$$x’=x-vt$$
$$\tau=\varphi(v)\beta\left(t-\frac{v}{c^2}x\right),$$
$$\xi=\varphi(v)\beta(x-vt),$$
$$\eta=\varphi(v)y,$$
$$\zeta=\varphi(v)z.$$
$$\beta=\frac{1}{\sqrt{1-(v/c)^2}},$$
$$\varphi(v)=\frac{a(v)}{\sqrt{1-(v/c)^2}}$$
$$x^2+y^2+z^2=c^2 t^2$$
$$\xi^2+\eta^2+\zeta^2=c^2 \tau^2$$
$$t’=\varphi(-v)\cdot\beta(-v)\left(\tau+\frac{v}{c^2}\xi\right)=\\\varphi(v)\cdot\varphi(-v)t,$$
$$x’=\varphi(-v)\cdot\beta(-v)(\xi+vt)=\\ \varphi(v)\cdot\varphi(-v)x,$$
$$y’=\varphi(-v)\eta=\varphi(v)\cdot\varphi(-v)y,$$
$$z’=\varphi(-v)\zeta=\varphi(v)\cdot\varphi(-v)z.$$
$$\varphi(v)\cdot\varphi(-v)=1$$
$$x_1=vt,\space y_1=\frac{l}{\varphi(v)’},\space z_1=0.$$
$$x_2=vt,\space y_2=0,\space z_2=0.$$
$$\frac{l}{\varphi(v)}=\frac{l}{\varphi(-v)},$$
$$\varphi(v)=\varphi(-v)$$
$$\tau=\beta\cdot\left(t-\frac{v}{c^2}x\right),$$
$$\xi=\beta\cdot(x-vt),$$
$$\eta=y,\space \zeta=z.$$
$$\beta=\frac{1}{\sqrt{1-(v/c)^2}}$$
$$\xi^2+\eta^2+\zeta^2=R^2.$$
$$\left\{\frac{x}{\sqrt{1-(v/c)^2}}\right\}^2+y^2+z^2=R^2.$$
$$R\sqrt{1-(v/c)^2},\space R,\space R$$
$$1:\sqrt{1-(v/c)^2}$$
$$\tau=\left. \left(t-\frac{v}{c^2}x\right)\middle/\sqrt{1-\left(\frac{v}{c}\right)^2}.\right.$$
$$x=vt$$
$$\tau=t\sqrt{1-\left(\frac{v}{c}\right)^2}=\\t-\left\{1-\sqrt{1-\left(\frac{v}{c}\right)^2}\right\}t$$
$$\left\{1-\sqrt{1-(v/c)^2}\right\}$$
$$\xi=w_{\xi}\tau,\space \eta=w_{\eta}\tau,\space \zeta=0$$
$$x=\frac{w_{\xi}+v}{1+(vw_{\xi}/c^2)}t,$$
$$y=\frac{\sqrt{1-(v/c)^2}}{1+(vw_{\xi}/c^2)}w_{\eta}t,$$
$$z=0.$$
$$U^2=\left(\frac{dx}{dt}\right)^2+\left(\frac{dy}{dt}\right)^2,$$
$$w^2=(w_{\xi})^2+(w_{\eta})^2,$$
$$\alpha=arctan(w_{\eta}/w_{\xi})$$
$$U=\frac{\sqrt{(v^2+w^2+2vw\space cos\space \alpha)-(vw\space sin\space\alpha/c)^2}}{1+(vw\space cos \space\alpha/c^2)}.$$
$$U=\frac{v+w}{1+(vw/c^2)}.$$
$$U=c\frac{2c-\kappa-\lambda}{2c-\kappa-\lambda+\frac{\kappa\lambda}{c}}<c.$$
$$U=\frac{c+w}{1+(w/c)}=c.$$
$$\frac{v+w}{1+(vw/c^2)}$$
相対性理論の前までは速度は一つの物理量として自由に加減できたのですが、光速が不変とわかったとき、速度に関わる法則を見直さなければならなくなり、それまで不変としてきた時間や空間を可変にすることで法則の維持を図ったのだと思います。それを実証する為に今でも観測や実験が繰り返されているのでしょう。
流石にアクティブバンドフィルターは期待通りの性能を出せました。低周波領域でもオペアンプを使えば部品点数も少なく理想的なフィルタが作れそうです。続いて信号の分離性を高めるためQの高いフィルタで実験してみました。
R1=220200Ω
R2=4771Ω
R3=4630Ω
C1=2677pF
IC=UPC741C
Q=46.851
f0=12649.593Hz
このくらいのQであれば信号の分離ができそうです。
部品点数も少なくQが高いバンドフィルタを作ることができました。これであればPCのサウンドライン出力に複数の信号を混合し受け側で分離すればライン1チャンネルを複数チャンネルにすることができそうです。1つのプログラム、1つのチャンネル、1つの受け側となるので波形単位の制御が必要なデジタル信号処理にも耐えられると思います。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 7; size_t i, j, start, end; size_t frequency = 400; size_t sampling = 384000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; for (i = start, j = 0; i < end; i += 2) { if (j == 0) { valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2)); valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } lpWave[i] = lpData[j]; ++j; if (j >= valWavelength) { j = 0; free(lpData); } } lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start+1, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
パッシブバンドフィルタが上手くいかなかったのでオペアンプを使用してアクティブバンドフィルタの実験を行いました。
R1=4649Ω
R2=4763Ω
R3=477.8kΩ
C1=287pF
C2=295pF
IC=UPC741C
Q=7.125
f0=16314.28Hz
可聴周波数をスイープして出力しフィルタを通した様子です。フィルタが機能しているのが判ります。しかし、複数の信号を狭い帯域に載せるにはもっとQが高くないと分離が上手くいかないような気がします。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 7; size_t i, j, start, end; size_t frequency = 400; size_t sampling = 384000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; for (i = start, j = 0; i < end; i += 2) { if (j == 0) { valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2)); valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } lpWave[i] = lpData[j]; ++j; if (j >= valWavelength) { j = 0; free(lpData); } } lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start+1, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
PCのサウンドラインに複数の信号を混合して出力し受け側で利用するためにはフィルタで分離する必要があります。早速簡単なLCフィルターで実験してみました。手持ちに丁度良いコイルが無かったので小信号トランスで代用しました。
R=1305Ω
L=494mH
C=4633pF
Q=7.912
f0=3326.791Hz
400Hzから20kHzまでスイープして信号を出力してみましたが、実用にできるほどの分離性はみられませんでした。
扱っているのが低周波なので性能の良いコイルを小さく作らないと使い物にならないことがわかりました。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 7; size_t i, j, start, end; size_t frequency = 400; size_t sampling = 384000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; for (i = start, j = 0; i < end; i += 2) { if (j == 0) { valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2)); valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } lpWave[i] = lpData[j]; ++j; if (j >= valWavelength) { j = 0; free(lpData); } } lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start+1, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
PCのサウンドライン出力に複数の周波数の信号を混合して出力し受け側で分離すれば1ラインを多重化できそうです。
二段増幅型バンドパスフィルター
1kHz
f0 = 1002.582Hz
Q = 20.788
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 6.8kΩ
R4, R5 = 10kΩ
C1, C2 = 0.01μF
6kHz
f0 = 5967.749Hz
Q = 20.788
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 6.8kΩ
R4, R5 = 10kΩ
C1, C2 = 1000pF + 680pF
11kHz
f0 = 11022.17Hz
Q = 22.854
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 3.9kΩ
R4, R5 = 10kΩ
C1, C2 = 1000pF
16kHz
f0 = 15921.863Hz
Q = 22.449
R1 = 330kΩ
R2, R3 = 10kΩ + 4.7kΩ
R4, R5 = 10kΩ
C1, C2 = 680pF
複数の周波数が混在した信号を利用する時にはフィルタで分離する必要があります。そのフィルタを評価するために指定範囲の周波数をスイープするジェネレーターを作りました。
#include <iostream> #include <windows.h> #include <math.h> #include <MMSystem.h> #pragma comment (lib, "winmm.lib") void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) { size_t wavelength = sampling / frequency; double d = 360.0 / wavelength; double pi = 3.14159265359; for (int i = 0; i < wavelength; i++) { lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi)); } } int main() { WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static WAVEHDR whdr; static LPWORD lpWave; static LPWORD lpData; // 最初と最後の1sは出力しないので3以上とする size_t terms = 7; size_t i, j, start, end; size_t frequency = 400; size_t sampling = 384000; size_t wavelength = sampling / frequency; wavelength = sampling / frequency; wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 2; wfe.wBitsPerSample = 16; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.nSamplesPerSec = (DWORD)sampling; wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign; waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL); lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms); end = sampling * wfe.nChannels * 1; WORD amplitude = 32767; for (i = 0; i < end; i++) { lpWave[i] = 0; } // 最初の1sは出力しない start = sampling * wfe.nChannels * 1; end = wfe.nChannels * sampling * terms; // 最後の1sは出力しない end -= sampling * wfe.nChannels * 1; size_t valWavelength; size_t valFrequency; for (i = start, j = 0; i < end; i += 2) { if (j == 0) { valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2)); valWavelength = sampling / valFrequency; lpData = (LPWORD)calloc(sizeof(WORD), valWavelength); createWave(lpData, valFrequency, sampling, amplitude); } lpWave[i] = lpData[j]; ++j; if (j >= valWavelength) { j = 0; free(lpData); } } lpData = (LPWORD)calloc(sizeof(WORD), wavelength); createWave(lpData, frequency, sampling, amplitude); for (i = start+1, j = 0; i < end; i += 2) { lpWave[i] = lpData[j]; ++j; if (j >= wavelength) { j = 0; } } free(lpData); whdr.lpData = (LPSTR)lpWave; whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms; whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; whdr.dwLoops = 1; waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR)); char str[128]; std::cout << "hello, world\n"; std::cin >> str; }
Flip Flops
ChatGPTに聞いてみた。
User
DM74LS74Nは何ですか。
ChatGPT
DM74LS74Nは、デュアルDフリップフロップ(Dual D Flip-Flop)IC(集積回路)の1つです。このICは、2つのDフリップフロップを持っており、デジタル回路においてデータの格納や信号の同期などに使用されます。
DM74LS74Nは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、2つのDフリップフロップがあり、それぞれのフリップフロップには、D入力ピン、クロック入力ピン、セット入力ピン、リセット入力ピン、Q出力ピン、Qバー出力ピンがあります。
DM74LS74Nは、高速なデータの格納や同期、信号のフィルタリングなどに適しています。また、このICは、デジタルシステムにおけるカウンティングやタイミング、シーケンシャルロジック回路の実装などに広く使用されています。
Hex Schmitt Inverter
https://toshiba.semicon-storage.com/info/docget.jsp?did=9945&prodName=TC74HC14AP
ChatGPTに聞いてみた。
User
74HC14APは何ですか。
ChatGPT
74HC14APは、インバータ(Inverter)IC(集積回路)の1つです。このICは、6つのインバータを持っており、入力信号を反転し、出力信号を生成することができます。また、このICは、高速で動作し、低消費電力であるため、多くのデジタルシステムに適しています。
74HC14APは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、6つのインバータがあり、それぞれのインバータには、入力ピンと出力ピンがあります。
74HC14APは、高速な信号反転や駆動、多くのデジタルシステムでの信号調整などのアプリケーションに適しています。また、このICは、パルスジェネレーション、クロックドライバ、バッファリングなどのために、広く使用されています。
QuadrupleBus BufferGatesWith 3-StateOutputs
http://www.ti.com/lit/ds/scls104e/scls104e.pdf?ts=1591310379048
ChatGPTに聞いてみた。
User
SN74HC125Nは何ですか。
ChatGPT
SN74HC125Nは、バッファ/ラインドライバ(Buffer/Line Driver)IC(集積回路)の1つです。このICは、4つのバッファを持っており、入力信号を増幅し、出力信号を駆動することができます。また、このICは、高速で動作し、消費電力が少ないため、多くのデジタルシステムに適しています。
SN74HC125Nは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、4つのバッファがあり、それぞれのバッファには、入力ピンと出力ピンがあります。また、バッファは、3つのステートメントコントロール入力(G、OE、nOE)を持っています。Gは、全体のICを有効化または無効化するために使用されます。OEは、すべてのバッファの出力を有効化または無効化するために使用されます。nOEは、単一のバッファの出力を有効化または無効化するために使用されます。
SN74HC125Nは、高速な信号増幅や駆動、多くのデジタルシステムでの信号調整などのアプリケーションに適しています。また、このICは、信号増幅、バッファリング、レベル変換などのために、広く使用されています。