2レベルインバータを自作した

2レベルインバータを自作しました。

スイッチング素子はIGBTを使用しています。ゲートドライブ回路は基板制作時にフットプリントのミスがあったため、パターンカットして使いました。

メインコントローラはRaspberry-Pi-Picoを使用しています。クロック周波数はオーバークロックさせて250MHzで使っています。メインコントローラに可変抵抗をつないで、その値をもとに加速度を制御しています。

GitHubにKiCad回路図とソースコードを載せています。

github.com

※回路の保証はありませんので、自己責任で製作してください。AC100Vを扱うため、誤った扱いをすると危険です。

#include 
#include 
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"

#define GPIO_U 8
#define GPIO_V 9
#define GPIO_W 10
#define GPIO_SD 11
// #define GPIO_PLS 12
// #define GPIO_DIR 13
#define ADC0_PIN 26
// #define GPIO_CLR 28

#define fs 40000.0
#define ARR_LEN 1024
#define LEN(array) (sizeof(array) / sizeof(array[0]))

void gpio_interrupt_callback(uint gpio, uint32_t emask);

int pulse_mode = 0;      // パルスモード
float modulated_freq = 0;  // 変調波(モーターの周波数)
float carrier_freq = 0;  // 搬送波(スイッチング周波数)

float voltage = 0;
float adc_accl = 0;
int adc_val = 0;
float accl = 0;
int sin_arr[ARR_LEN] = {0, 3, 6, 9, 12, 15, 18, 21, 25, 28, 31, 34, 37, 40, 43, 47, 50, 53, 56, 59, 62, 65, 68, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 106, 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142, 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178, 181, 184, 187, 190, 193, 195, 198, 201, 204, 207, 210, 213, 216, 218, 221, 224, 227, 230, 233, 235, 238, 241, 244, 246, 249, 252, 255, 257, 260, 263, 265, 268, 271, 273, 276, 279, 281, 284, 287, 289, 292, 294, 297, 299, 302, 304, 307, 310, 312, 314, 317, 319, 322, 324, 327, 329, 332, 334, 336, 339, 341, 343, 346, 348, 350, 353, 355, 357, 359, 362, 364, 366, 368, 370, 372, 375, 377, 379, 381, 383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, 413, 414, 416, 418, 420, 422, 423, 425, 427, 429, 430, 432, 434, 435, 437, 439, 440, 442, 443, 445, 447, 448, 450, 451, 453, 454, 455, 457, 458, 460, 461, 462, 464, 465, 466, 468, 469, 470, 471, 473, 474, 475, 476, 477, 478, 479, 481, 482, 483, 484, 485, 486, 487, 488, 489, 489, 490, 491, 492, 493, 494, 495, 495, 496, 497, 498, 498, 499, 500, 500, 501, 502, 502, 503, 503, 504, 504, 505, 505, 506, 506, 507, 507, 508, 508, 508, 509, 509, 509, 510, 510, 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, 510, 510, 510, 510, 509, 509, 509, 508, 508, 508, 507, 507, 506, 506, 505, 505, 504, 504, 503, 503, 502, 502, 501, 500, 500, 499, 498, 498, 497, 496, 495, 495, 494, 493, 492, 491, 490, 489, 489, 488, 487, 486, 485, 484, 483, 482, 481, 479, 478, 477, 476, 475, 474, 473, 471, 470, 469, 468, 466, 465, 464, 462, 461, 460, 458, 457, 455, 454, 453, 451, 450, 448, 447, 445, 443, 442, 440, 439, 437, 435, 434, 432, 430, 429, 427, 425, 423, 422, 420, 418, 416, 414, 413, 411, 409, 407, 405, 403, 401, 399, 397, 395, 393, 391, 389, 387, 385, 383, 381, 379, 377, 375, 372, 370, 368, 366, 364, 362, 359, 357, 355, 353, 350, 348, 346, 343, 341, 339, 336, 334, 332, 329, 327, 324, 322, 319, 317, 314, 312, 310, 307, 304, 302, 299, 297, 294, 292, 289, 287, 284, 281, 279, 276, 273, 271, 268, 265, 263, 260, 257, 255, 252, 249, 246, 244, 241, 238, 235, 233, 230, 227, 224, 221, 218, 216, 213, 210, 207, 204, 201, 198, 195, 193, 190, 187, 184, 181, 178, 175, 172, 169, 166, 163, 160, 157, 154, 151, 148, 145, 142, 139, 136, 133, 130, 127, 124, 121, 118, 115, 112, 109, 106, 102, 99, 96, 93, 90, 87, 84, 81, 78, 75, 72, 68, 65, 62, 59, 56, 53, 50, 47, 43, 40, 37, 34, 31, 28, 25, 21, 18, 15, 12, 9, 6, 3, 0, -4, -7, -10, -13, -16, -19, -22, -26, -29, -32, -35, -38, -41, -44, -48, -51, -54, -57, -60, -63, -66, -69, -73, -76, -79, -82, -85, -88, -91, -94, -97, -100, -103, -107, -110, -113, -116, -119, -122, -125, -128, -131, -134, -137, -140, -143, -146, -149, -152, -155, -158, -161, -164, -167, -170, -173, -176, -179, -182, -185, -188, -191, -194, -196, -199, -202, -205, -208, -211, -214, -217, -219, -222, -225, -228, -231, -234, -236, -239, -242, -245, -247, -250, -253, -256, -258, -261, -264, -266, -269, -272, -274, -277, -280, -282, -285, -288, -290, -293, -295, -298, -300, -303, -305, -308, -311, -313, -315, -318, -320, -323, -325, -328, -330, -333, -335, -337, -340, -342, -344, -347, -349, -351, -354, -356, -358, -360, -363, -365, -367, -369, -371, -373, -376, -378, -380, -382, -384, -386, -388, -390, -392, -394, -396, -398, -400, -402, -404, -406, -408, -410, -412, -414, -415, -417, -419, -421, -423, -424, -426, -428, -430, -431, -433, -435, -436, -438, -440, -441, -443, -444, -446, -448, -449, -451, -452, -454, -455, -456, -458, -459, -461, -462, -463, -465, -466, -467, -469, -470, -471, -472, -474, -475, -476, -477, -478, -479, -480, -482, -483, -484, -485, -486, -487, -488, -489, -490, -490, -491, -492, -493, -494, -495, -496, -496, -497, -498, -499, -499, -500, -501, -501, -502, -503, -503, -504, -504, -505, -505, -506, -506, -507, -507, -508, -508, -509, -509, -509, -510, -510, -510, -511, -511, -511, -511, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -512, -511, -511, -511, -511, -510, -510, -510, -509, -509, -509, -508, -508, -507, -507, -506, -506, -505, -505, -504, -504, -503, -503, -502, -501, -501, -500, -499, -499, -498, -497, -496, -496, -495, -494, -493, -492, -491, -490, -490, -489, -488, -487, -486, -485, -484, -483, -482, -480, -479, -478, -477, -476, -475, -474, -472, -471, -470, -469, -467, -466, -465, -463, -462, -461, -459, -458, -456, -455, -454, -452, -451, -449, -448, -446, -444, -443, -441, -440, -438, -436, -435, -433, -431, -430, -428, -426, -424, -423, -421, -419, -417, -415, -414, -412, -410, -408, -406, -404, -402, -400, -398, -396, -394, -392, -390, -388, -386, -384, -382, -380, -378, -376, -373, -371, -369, -367, -365, -363, -360, -358, -356, -354, -351, -349, -347, -344, -342, -340, -337, -335, -333, -330, -328, -325, -323, -320, -318, -315, -313, -311, -308, -305, -303, -300, -298, -295, -293, -290, -288, -285, -282, -280, -277, -274, -272, -269, -266, -264, -261, -258, -256, -253, -250, -247, -245, -242, -239, -236, -234, -231, -228, -225, -222, -219, -217, -214, -211, -208, -205, -202, -199, -196, -194, -191, -188, -185, -182, -179, -176, -173, -170, -167, -164, -161, -158, -155, -152, -149, -146, -143, -140, -137, -134, -131, -128, -125, -122, -119, -116, -113, -110, -107, -103, -100, -97, -94, -91, -88, -85, -82, -79, -76, -73, -69, -66, -63, -60, -57, -54, -51, -48, -44, -41, -38, -35, -32, -29, -26, -22, -19, -16, -13, -10, -7, -4};
int tri_arr[ARR_LEN] = {0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -22, -24, -26, -28, -30, -32, -34, -36, -38, -40, -42, -44, -46, -48, -50, -52, -54, -56, -58, -60, -62, -64, -66, -68, -70, -72, -74, -76, -78, -80, -82, -84, -86, -88, -90, -92, -94, -96, -98, -100, -102, -104, -106, -108, -110, -112, -114, -116, -118, -120, -122, -124, -126, -128, -130, -132, -134, -136, -138, -140, -142, -144, -146, -148, -150, -152, -154, -156, -158, -160, -162, -164, -166, -168, -170, -172, -174, -176, -178, -180, -182, -184, -186, -188, -190, -192, -194, -196, -198, -200, -202, -204, -206, -208, -210, -212, -214, -216, -218, -220, -222, -224, -226, -228, -230, -232, -234, -236, -238, -240, -242, -244, -246, -248, -250, -252, -254, -256, -258, -260, -262, -264, -266, -268, -270, -272, -274, -276, -278, -280, -282, -284, -286, -288, -290, -292, -294, -296, -298, -300, -302, -304, -306, -308, -310, -312, -314, -316, -318, -320, -322, -324, -326, -328, -330, -332, -334, -336, -338, -340, -342, -344, -346, -348, -350, -352, -354, -356, -358, -360, -362, -364, -366, -368, -370, -372, -374, -376, -378, -380, -382, -384, -386, -388, -390, -392, -394, -396, -398, -400, -402, -404, -406, -408, -410, -412, -414, -416, -418, -420, -422, -424, -426, -428, -430, -432, -434, -436, -438, -440, -442, -444, -446, -448, -450, -452, -454, -456, -458, -460, -462, -464, -466, -468, -470, -472, -474, -476, -478, -480, -482, -484, -486, -488, -490, -492, -494, -496, -498, -500, -502, -504, -506, -508, -510, -512, -510, -508, -506, -504, -502, -500, -498, -496, -494, -492, -490, -488, -486, -484, -482, -480, -478, -476, -474, -472, -470, -468, -466, -464, -462, -460, -458, -456, -454, -452, -450, -448, -446, -444, -442, -440, -438, -436, -434, -432, -430, -428, -426, -424, -422, -420, -418, -416, -414, -412, -410, -408, -406, -404, -402, -400, -398, -396, -394, -392, -390, -388, -386, -384, -382, -380, -378, -376, -374, -372, -370, -368, -366, -364, -362, -360, -358, -356, -354, -352, -350, -348, -346, -344, -342, -340, -338, -336, -334, -332, -330, -328, -326, -324, -322, -320, -318, -316, -314, -312, -310, -308, -306, -304, -302, -300, -298, -296, -294, -292, -290, -288, -286, -284, -282, -280, -278, -276, -274, -272, -270, -268, -266, -264, -262, -260, -258, -256, -254, -252, -250, -248, -246, -244, -242, -240, -238, -236, -234, -232, -230, -228, -226, -224, -222, -220, -218, -216, -214, -212, -210, -208, -206, -204, -202, -200, -198, -196, -194, -192, -190, -188, -186, -184, -182, -180, -178, -176, -174, -172, -170, -168, -166, -164, -162, -160, -158, -156, -154, -152, -150, -148, -146, -144, -142, -140, -138, -136, -134, -132, -130, -128, -126, -124, -122, -120, -118, -116, -114, -112, -110, -108, -106, -104, -102, -100, -98, -96, -94, -92, -90, -88, -86, -84, -82, -80, -78, -76, -74, -72, -70, -68, -66, -64, -62, -60, -58, -56, -54, -52, -50, -48, -46, -44, -42, -40, -38, -36, -34, -32, -30, -28, -26, -24, -22, -20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480, 482, 484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 506, 508, 510, 511, 510, 508, 506, 504, 502, 500, 498, 496, 494, 492, 490, 488, 486, 484, 482, 480, 478, 476, 474, 472, 470, 468, 466, 464, 462, 460, 458, 456, 454, 452, 450, 448, 446, 444, 442, 440, 438, 436, 434, 432, 430, 428, 426, 424, 422, 420, 418, 416, 414, 412, 410, 408, 406, 404, 402, 400, 398, 396, 394, 392, 390, 388, 386, 384, 382, 380, 378, 376, 374, 372, 370, 368, 366, 364, 362, 360, 358, 356, 354, 352, 350, 348, 346, 344, 342, 340, 338, 336, 334, 332, 330, 328, 326, 324, 322, 320, 318, 316, 314, 312, 310, 308, 306, 304, 302, 300, 298, 296, 294, 292, 290, 288, 286, 284, 282, 280, 278, 276, 274, 272, 270, 268, 266, 264, 262, 260, 258, 256, 254, 252, 250, 248, 246, 244, 242, 240, 238, 236, 234, 232, 230, 228, 226, 224, 222, 220, 218, 216, 214, 212, 210, 208, 206, 204, 202, 200, 198, 196, 194, 192, 190, 188, 186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 160, 158, 156, 154, 152, 150, 148, 146, 144, 142, 140, 138, 136, 134, 132, 130, 128, 126, 124, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102, 100, 98, 96, 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2};
int saw_arr[ARR_LEN] = {-512, -511, -510, -509, -508, -507, -506, -505, -504, -503, -502, -501, -500, -499, -498, -497, -496, -495, -494, -493, -492, -491, -490, -489, -488, -487, -486, -485, -484, -483, -482, -481, -480, -479, -478, -477, -476, -475, -474, -473, -472, -471, -470, -469, -468, -467, -466, -465, -464, -463, -462, -461, -460, -459, -458, -457, -456, -455, -454, -453, -452, -451, -450, -449, -448, -447, -446, -445, -444, -443, -442, -441, -440, -439, -438, -437, -436, -435, -434, -433, -432, -431, -430, -429, -428, -427, -426, -425, -424, -423, -422, -421, -420, -419, -418, -417, -416, -415, -414, -413, -412, -411, -410, -409, -408, -407, -406, -405, -404, -403, -402, -401, -400, -399, -398, -397, -396, -395, -394, -393, -392, -391, -390, -389, -388, -387, -386, -385, -384, -383, -382, -381, -380, -379, -378, -377, -376, -375, -374, -373, -372, -371, -370, -369, -368, -367, -366, -365, -364, -363, -362, -361, -360, -359, -358, -357, -356, -355, -354, -353, -352, -351, -350, -349, -348, -347, -346, -345, -344, -343, -342, -341, -340, -339, -338, -337, -336, -335, -334, -333, -332, -331, -330, -329, -328, -327, -326, -325, -324, -323, -322, -321, -320, -319, -318, -317, -316, -315, -314, -313, -312, -311, -310, -309, -308, -307, -306, -305, -304, -303, -302, -301, -300, -299, -298, -297, -296, -295, -294, -293, -292, -291, -290, -289, -288, -287, -286, -285, -284, -283, -282, -281, -280, -279, -278, -277, -276, -275, -274, -273, -272, -271, -270, -269, -268, -267, -266, -265, -264, -263, -262, -261, -260, -259, -258, -257, -256, -255, -254, -253, -252, -251, -250, -249, -248, -247, -246, -245, -244, -243, -242, -241, -240, -239, -238, -237, -236, -235, -234, -233, -232, -231, -230, -229, -228, -227, -226, -225, -224, -223, -222, -221, -220, -219, -218, -217, -216, -215, -214, -213, -212, -211, -210, -209, -208, -207, -206, -205, -204, -203, -202, -201, -200, -199, -198, -197, -196, -195, -194, -193, -192, -191, -190, -189, -188, -187, -186, -185, -184, -183, -182, -181, -180, -179, -178, -177, -176, -175, -174, -173, -172, -171, -170, -169, -168, -167, -166, -165, -164, -163, -162, -161, -160, -159, -158, -157, -156, -155, -154, -153, -152, -151, -150, -149, -148, -147, -146, -145, -144, -143, -142, -141, -140, -139, -138, -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511};
int wide_arr[ARR_LEN] = {511, 509, 506, 503, 500, 497, 494, 491, 488, 485, 482, 479, 476, 473, 470, 467, 464, 461, 458, 455, 452, 449, 446, 443, 440, 437, 434, 431, 428, 425, 422, 419, 416, 413, 410, 407, 404, 401, 398, 395, 392, 389, 386, 383, 380, 377, 374, 371, 368, 365, 362, 359, 356, 353, 350, 347, 344, 341, 338, 335, 332, 329, 326, 323, 320, 317, 314, 311, 308, 305, 302, 299, 296, 293, 290, 287, 284, 281, 278, 275, 272, 269, 266, 263, 260, 257, 254, 251, 248, 245, 242, 239, 236, 233, 230, 227, 224, 221, 218, 215, 212, 209, 206, 203, 200, 197, 194, 191, 188, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, 128, 125, 122, 119, 116, 113, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 11, 8, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98, 101, 104, 107, 110, 113, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 188, 191, 194, 197, 200, 203, 206, 209, 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, 260, 263, 266, 269, 272, 275, 278, 281, 284, 287, 290, 293, 296, 299, 302, 305, 308, 311, 314, 317, 320, 323, 326, 329, 332, 335, 338, 341, 344, 347, 350, 353, 356, 359, 362, 365, 368, 371, 374, 377, 380, 383, 386, 389, 392, 395, 398, 401, 404, 407, 410, 413, 416, 419, 422, 425, 428, 431, 434, 437, 440, 443, 446, 449, 452, 455, 458, 461, 464, 467, 470, 473, 476, 479, 482, 485, 488, 491, 494, 497, 500, 503, 506, 509, -512, -509, -506, -503, -500, -497, -494, -491, -488, -485, -482, -479, -476, -473, -470, -467, -464, -461, -458, -455, -452, -449, -446, -443, -440, -437, -434, -431, -428, -425, -422, -419, -416, -413, -410, -407, -404, -401, -398, -395, -392, -389, -386, -383, -380, -377, -374, -371, -368, -365, -362, -359, -356, -353, -350, -347, -344, -341, -338, -335, -332, -329, -326, -323, -320, -317, -314, -311, -308, -305, -302, -299, -296, -293, -290, -287, -284, -281, -278, -275, -272, -269, -266, -263, -260, -257, -254, -251, -248, -245, -242, -239, -236, -233, -230, -227, -224, -221, -218, -215, -212, -209, -206, -203, -200, -197, -194, -191, -188, -185, -182, -179, -176, -173, -170, -167, -164, -161, -158, -155, -152, -149, -146, -143, -140, -137, -134, -131, -128, -125, -122, -119, -116, -113, -110, -107, -104, -101, -98, -95, -92, -89, -86, -83, -80, -77, -74, -71, -68, -65, -62, -59, -56, -53, -50, -47, -44, -41, -38, -35, -32, -29, -26, -23, -20, -17, -14, -11, -8, -5, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -5, -8, -11, -14, -17, -20, -23, -26, -29, -32, -35, -38, -41, -44, -47, -50, -53, -56, -59, -62, -65, -68, -71, -74, -77, -80, -83, -86, -89, -92, -95, -98, -101, -104, -107, -110, -113, -116, -119, -122, -125, -128, -131, -134, -137, -140, -143, -146, -149, -152, -155, -158, -161, -164, -167, -170, -173, -176, -179, -182, -185, -188, -191, -194, -197, -200, -203, -206, -209, -212, -215, -218, -221, -224, -227, -230, -233, -236, -239, -242, -245, -248, -251, -254, -257, -260, -263, -266, -269, -272, -275, -278, -281, -284, -287, -290, -293, -296, -299, -302, -305, -308, -311, -314, -317, -320, -323, -326, -329, -332, -335, -338, -341, -344, -347, -350, -353, -356, -359, -362, -365, -368, -371, -374, -377, -380, -383, -386, -389, -392, -395, -398, -401, -404, -407, -410, -413, -416, -419, -422, -425, -428, -431, -434, -437, -440, -443, -446, -449, -452, -455, -458, -461, -464, -467, -470, -473, -476, -479, -482, -485, -488, -491, -494, -497, -500, -503, -506, -509};
unsigned int rand_arr[ARR_LEN] = {747, 849, 931, 877, 147, 781, 976, 511, 12, 765, 398, 577, 922, 784, 357, 466, 576, 57, 523, 869, 443, 295, 659, 123, 145, 248, 573, 202, 930, 795, 802, 564, 996, 97, 182, 950, 759, 1012, 217, 325, 128, 353, 573, 1010, 1014, 53, 71, 681, 277, 857, 217, 490, 806, 732, 20, 407, 88, 80, 562, 175, 912, 307, 618, 265, 498, 353, 825, 928, 7, 881, 889, 385, 418, 417, 628, 389, 386, 934, 823, 348, 36, 476, 887, 894, 603, 283, 432, 62, 112, 459, 601, 371, 848, 749, 262, 561, 485, 637, 124, 180, 317, 746, 250, 844, 450, 162, 696, 815, 866, 268, 589, 982, 282, 604, 37, 552, 754, 389, 420, 618, 164, 839, 307, 665, 655, 1022, 453, 393, 148, 358, 78, 350, 56, 590, 261, 285, 364, 383, 946, 467, 58, 822, 729, 778, 852, 961, 808, 78, 974, 131, 834, 331, 646, 343, 875, 403, 237, 752, 754, 554, 891, 470, 957, 702, 80, 624, 725, 500, 473, 316, 277, 919, 378, 1018, 138, 505, 431, 838, 175, 206, 100, 215, 937, 140, 778, 220, 672, 211, 189, 849, 422, 250, 453, 529, 460, 916, 107, 55, 497, 49, 174, 557, 346, 323, 344, 666, 49, 451, 820, 193, 483, 876, 468, 747, 141, 755, 90, 230, 894, 553, 666, 319, 180, 708, 511, 700, 574, 338, 552, 161, 15, 71, 449, 142, 284, 881, 284, 48, 663, 605, 968, 31, 793, 884, 742, 866, 859, 635, 450, 500, 644, 561, 412, 993, 45, 787, 847, 333, 659, 715, 846, 557, 519, 64, 456, 3, 380, 774, 186, 398, 373, 762, 249, 312, 566, 107, 882, 311, 383, 216, 900, 427, 608, 938, 810, 771, 299, 841, 306, 364, 707, 96, 830, 26, 141, 92, 16, 390, 510, 1019, 608, 377, 162, 876, 38, 45, 213, 915, 775, 823, 150, 888, 147, 27, 700, 855, 489, 554, 1017, 861, 841, 838, 224, 243, 494, 669, 753, 191, 292, 98, 104, 891, 923, 218, 4, 195, 481, 150, 291, 498, 19, 31, 33, 844, 314, 67, 94, 58, 932, 811, 458, 822, 305, 427, 547, 460, 270, 154, 626, 543, 786, 132, 922, 154, 431, 499, 82, 170, 297, 164, 756, 187, 449, 554, 495, 834, 759, 45, 984, 479, 722, 365, 486, 457, 949, 216, 78, 417, 894, 608, 996, 473, 255, 12, 50, 723, 1009, 548, 338, 927, 931, 747, 186, 18, 748, 526, 953, 293, 763, 577, 934, 389, 315, 189, 855, 905, 113, 731, 827, 663, 920, 655, 209, 807, 214, 767, 329, 823, 325, 964, 468, 737, 980, 989, 37, 708, 438, 259, 59, 815, 460, 464, 716, 753, 74, 78, 958, 601, 58, 164, 199, 64, 21, 325, 652, 474, 760, 308, 674, 284, 856, 482, 139, 255, 624, 577, 435, 393, 660, 384, 86, 793, 638, 493, 703, 442, 783, 108, 297, 49, 459, 1001, 572, 1004, 251, 910, 482, 557, 756, 81, 998, 590, 944, 760, 627, 558, 150, 40, 390, 397, 620, 467, 92, 476, 39, 635, 148, 755, 630, 231, 327, 599, 461, 133, 716, 909, 778, 887, 185, 47, 426, 916, 58, 90, 824, 991, 554, 402, 572, 98, 104, 216, 904, 947, 36, 919, 938, 293, 831, 863, 225, 1022, 207, 891, 789, 577, 114, 65, 398, 167, 237, 305, 38, 927, 707, 452, 736, 998, 667, 399, 128, 636, 649, 441, 709, 209, 298, 529, 788, 719, 1011, 405, 777, 245, 671, 961, 274, 361, 310, 742, 156, 876, 441, 172, 278, 118, 740, 98, 902, 822, 14, 234, 153, 7, 995, 174, 793, 171, 251, 755, 25, 237, 654, 545, 115, 129, 678, 1007, 700, 144, 599, 834, 950, 222, 693, 908, 287, 263, 538, 903, 822, 471, 647, 917, 655, 6, 151, 887, 314, 496, 902, 745, 2, 129, 753, 1000, 618, 400, 66, 345, 95, 408, 383, 754, 833, 462, 868, 172, 73, 556, 745, 439, 36, 208, 306, 774, 131, 26, 6, 64, 397, 148, 930, 237, 818, 560, 999, 614, 179, 272, 453, 724, 438, 834, 68, 691, 142, 119, 308, 935, 574, 247, 888, 193, 807, 7, 191, 360, 301, 1021, 698, 680, 876, 760, 746, 295, 421, 102, 281, 774, 884, 437, 290, 126, 484, 374, 566, 185, 32, 42, 857, 52, 350, 351, 607, 998, 99, 930, 381, 694, 500, 702, 751, 246, 949, 506, 730, 49, 1005, 393, 888, 897, 796, 246, 127, 178, 694, 645, 167, 653, 924, 294, 633, 766, 924, 228, 998, 360, 113, 866, 820, 618, 247, 199, 690, 4, 395, 313, 305, 289, 805, 214, 800, 94, 1010, 375, 237, 278, 528, 505, 238, 348, 77, 978, 808, 297, 654, 336, 7, 447, 533, 744, 246, 341, 994, 614, 648, 942, 968, 373, 931, 190, 525, 112, 416, 570, 181, 147, 902, 847, 965, 713, 219, 149, 825, 918, 7, 839, 254, 813, 518, 992, 165, 196, 645, 223, 89, 81, 49, 726, 836, 144, 308, 515, 468, 14, 196, 222, 763, 249, 938, 989, 190, 326, 242, 1, 407, 564, 60, 500, 705, 226, 953, 687, 856, 210, 335, 821, 995, 802, 916, 964, 428, 411, 474, 695, 309, 823, 666, 937, 1011, 962, 79, 590, 341, 809, 990, 701, 888, 990, 514, 314, 376, 593, 64, 600, 480, 134, 325, 342, 565, 944, 208, 936, 727, 668, 882, 202, 538, 850, 926, 34, 147, 186, 63, 325, 195, 237, 543, 311, 13, 342, 520, 727, 275, 415, 320, 112, 564, 682, 164, 285, 762, 55, 945, 383, 713, 742, 628, 624, 914, 452, 242, 181, 244, 642, 896, 881, 810, 571, 579, 818, 868, 204, 845, 188, 339, 450, 43, 943, 416, 592, 159, 144, 147, 977, 9, 252, 1014, 14, 704, 709, 888, 66, 626, 59, 212, 425, 706, 587, 960, 913, 211, 47, 849, 835, 766, 325, 701, 70, 351, 289, 246, 267, 138, 942, 931, 982, 239, 603, 545, 922, 256, 679, 251, 551, 995, 557, 948, 658, 455, 455, 674, 989, 10, 698, 806, 179, 314, 903, 1014, 445, 431, 906, 282, 480, 798, 942, 724, 750, 444, 63, 337, 156, 201, 468, 985, 681, 53, 997, 911, 829, 349, 44};
//float sqrt_arr[ARR_LEN] = {0, 0.5, 0.71, 0.87, 1, 1.12, 1.22, 1.32, 1.41, 1.5, 1.58, 1.66, 1.73, 1.8, 1.87, 1.94, 2, 2.06, 2.12, 2.18, 2.24, 2.29, 2.35, 2.4, 2.45, 2.5, 2.55, 2.6, 2.65, 2.69, 2.74, 2.78, 2.83, 2.87, 2.92, 2.96, 3, 3.04, 3.08, 3.12, 3.16, 3.2, 3.24, 3.28, 3.32, 3.35, 3.39, 3.43, 3.46, 3.5, 3.54, 3.57, 3.61, 3.64, 3.67, 3.71, 3.74, 3.77, 3.81, 3.84, 3.87, 3.91, 3.94, 3.97, 4, 4.03, 4.06, 4.09, 4.12, 4.15, 4.18, 4.21, 4.24, 4.27, 4.3, 4.33, 4.36, 4.39, 4.42, 4.44, 4.47, 4.5, 4.53, 4.56, 4.58, 4.61, 4.64, 4.66, 4.69, 4.72, 4.74, 4.77, 4.8, 4.82, 4.85, 4.87, 4.9, 4.92, 4.95, 4.97, 5, 5.02, 5.05, 5.07, 5.1, 5.12, 5.15, 5.17, 5.2, 5.22, 5.24, 5.27, 5.29, 5.32, 5.34, 5.36, 5.39, 5.41, 5.43, 5.45, 5.48, 5.5, 5.52, 5.55, 5.57, 5.59, 5.61, 5.63, 5.66, 5.68, 5.7, 5.72, 5.74, 5.77, 5.79, 5.81, 5.83, 5.85, 5.87, 5.89, 5.92, 5.94, 5.96, 5.98, 6, 6.02, 6.04, 6.06, 6.08, 6.1, 6.12, 6.14, 6.16, 6.18, 6.2, 6.22, 6.24, 6.26, 6.28, 6.3, 6.32, 6.34, 6.36, 6.38, 6.4, 6.42, 6.44, 6.46, 6.48, 6.5, 6.52, 6.54, 6.56, 6.58, 6.6, 6.61, 6.63, 6.65, 6.67, 6.69, 6.71, 6.73, 6.75, 6.76, 6.78, 6.8, 6.82, 6.84, 6.86, 6.87, 6.89, 6.91, 6.93, 6.95, 6.96, 6.98, 7, 7.02, 7.04, 7.05, 7.07, 7.09, 7.11, 7.12, 7.14, 7.16, 7.18, 7.19, 7.21, 7.23, 7.25, 7.26, 7.28, 7.3, 7.31, 7.33, 7.35, 7.37, 7.38, 7.4, 7.42, 7.43, 7.45, 7.47, 7.48, 7.5, 7.52, 7.53, 7.55, 7.57, 7.58, 7.6, 7.62, 7.63, 7.65, 7.66, 7.68, 7.7, 7.71, 7.73, 7.75, 7.76, 7.78, 7.79, 7.81, 7.83, 7.84, 7.86, 7.87, 7.89, 7.91, 7.92, 7.94, 7.95, 7.97, 7.98, 8, 8.02, 8.03, 8.05, 8.06, 8.08, 8.09, 8.11, 8.12, 8.14, 8.15, 8.17, 8.19, 8.2, 8.22, 8.23, 8.25, 8.26, 8.28, 8.29, 8.31, 8.32, 8.34, 8.35, 8.37, 8.38, 8.4, 8.41, 8.43, 8.44, 8.46, 8.47, 8.49, 8.5, 8.51, 8.53, 8.54, 8.56, 8.57, 8.59, 8.6, 8.62, 8.63, 8.65, 8.66, 8.67, 8.69, 8.7, 8.72, 8.73, 8.75, 8.76, 8.77, 8.79, 8.8, 8.82, 8.83, 8.85, 8.86, 8.87, 8.89, 8.9, 8.92, 8.93, 8.94, 8.96, 8.97, 8.99, 9, 9.01, 9.03, 9.04, 9.06, 9.07, 9.08, 9.1, 9.11, 9.12, 9.14, 9.15, 9.17, 9.18, 9.19, 9.21, 9.22, 9.23, 9.25, 9.26, 9.27, 9.29, 9.3, 9.31, 9.33, 9.34, 9.35, 9.37, 9.38, 9.39, 9.41, 9.42, 9.43, 9.45, 9.46, 9.47, 9.49, 9.5, 9.51, 9.53, 9.54, 9.55, 9.57, 9.58, 9.59, 9.6, 9.62, 9.63, 9.64, 9.66, 9.67, 9.68, 9.7, 9.71, 9.72, 9.73, 9.75, 9.76, 9.77, 9.79, 9.8, 9.81, 9.82, 9.84, 9.85, 9.86, 9.87, 9.89, 9.9, 9.91, 9.92, 9.94, 9.95, 9.96, 9.97, 9.99, 10, 10.01, 10.02, 10.04, 10.05, 10.06, 10.07, 10.09, 10.1, 10.11, 10.12, 10.14, 10.15, 10.16, 10.17, 10.19, 10.2, 10.21, 10.22, 10.23, 10.25, 10.26, 10.27, 10.28, 10.3, 10.31, 10.32, 10.33, 10.34, 10.36, 10.37, 10.38, 10.39, 10.4, 10.42, 10.43, 10.44, 10.45, 10.46, 10.48, 10.49, 10.5, 10.51, 10.52, 10.54, 10.55, 10.56, 10.57, 10.58, 10.59, 10.61, 10.62, 10.63, 10.64, 10.65, 10.67, 10.68, 10.69, 10.7, 10.71, 10.72, 10.74, 10.75, 10.76, 10.77, 10.78, 10.79, 10.81, 10.82, 10.83, 10.84, 10.85, 10.86, 10.87, 10.89, 10.9, 10.91, 10.92, 10.93, 10.94, 10.95, 10.97, 10.98, 10.99, 11, 11.01, 11.02, 11.03, 11.05, 11.06, 11.07, 11.08, 11.09, 11.1, 11.11, 11.12, 11.14, 11.15, 11.16, 11.17, 11.18, 11.19, 11.2, 11.21, 11.22, 11.24, 11.25, 11.26, 11.27, 11.28, 11.29, 11.3, 11.31, 11.32, 11.34, 11.35, 11.36, 11.37, 11.38, 11.39, 11.4, 11.41, 11.42, 11.43, 11.45, 11.46, 11.47, 11.48, 11.49, 11.5, 11.51, 11.52, 11.53, 11.54, 11.55, 11.57, 11.58, 11.59, 11.6, 11.61, 11.62, 11.63, 11.64, 11.65, 11.66, 11.67, 11.68, 11.69, 11.7, 11.72, 11.73, 11.74, 11.75, 11.76, 11.77, 11.78, 11.79, 11.8, 11.81, 11.82, 11.83, 11.84, 11.85, 11.86, 11.87, 11.88, 11.9, 11.91, 11.92, 11.93, 11.94, 11.95, 11.96, 11.97, 11.98, 11.99, 12, 12.01, 12.02, 12.03, 12.04, 12.05, 12.06, 12.07, 12.08, 12.09, 12.1, 12.11, 12.12, 12.13, 12.14, 12.16, 12.17, 12.18, 12.19, 12.2, 12.21, 12.22, 12.23, 12.24, 12.25, 12.26, 12.27, 12.28, 12.29, 12.3, 12.31, 12.32, 12.33, 12.34, 12.35, 12.36, 12.37, 12.38, 12.39, 12.4, 12.41, 12.42, 12.43, 12.44, 12.45, 12.46, 12.47, 12.48, 12.49, 12.5, 12.51, 12.52, 12.53, 12.54, 12.55, 12.56, 12.57, 12.58, 12.59, 12.6, 12.61, 12.62, 12.63, 12.64, 12.65, 12.66, 12.67, 12.68, 12.69, 12.7, 12.71, 12.72, 12.73, 12.74, 12.75, 12.76, 12.77, 12.78, 12.79, 12.8, 12.81, 12.82, 12.83, 12.84, 12.85, 12.85, 12.86, 12.87, 12.88, 12.89, 12.9, 12.91, 12.92, 12.93, 12.94, 12.95, 12.96, 12.97, 12.98, 12.99, 13, 13.01, 13.02, 13.03, 13.04, 13.05, 13.06, 13.07, 13.08, 13.09, 13.1, 13.11, 13.11, 13.12, 13.13, 13.14, 13.15, 13.16, 13.17, 13.18, 13.19, 13.2, 13.21, 13.22, 13.23, 13.24, 13.25, 13.26, 13.27, 13.28, 13.29, 13.29, 13.3, 13.31, 13.32, 13.33, 13.34, 13.35, 13.36, 13.37, 13.38, 13.39, 13.4, 13.41, 13.42, 13.43, 13.44, 13.44, 13.45, 13.46, 13.47, 13.48, 13.49, 13.5, 13.51, 13.52, 13.53, 13.54, 13.55, 13.56, 13.56, 13.57, 13.58, 13.59, 13.6, 13.61, 13.62, 13.63, 13.64, 13.65, 13.66, 13.67, 13.67, 13.68, 13.69, 13.7, 13.71, 13.72, 13.73, 13.74, 13.75, 13.76, 13.77, 13.77, 13.78, 13.79, 13.8, 13.81, 13.82, 13.83, 13.84, 13.85, 13.86, 13.87, 13.87, 13.88, 13.89, 13.9, 13.91, 13.92, 13.93, 13.94, 13.95, 13.96, 13.96, 13.97, 13.98, 13.99, 14, 14.01, 14.02, 14.03, 14.04, 14.04, 14.05, 14.06, 14.07, 14.08, 14.09, 14.1, 14.11, 14.12, 14.12, 14.13, 14.14, 14.15, 14.16, 14.17, 14.18, 14.19, 14.2, 14.2, 14.21, 14.22, 14.23, 14.24, 14.25, 14.26, 14.27, 14.27, 14.28, 14.29, 14.3, 14.31, 14.32, 14.33, 14.34, 14.34, 14.35, 14.36, 14.37, 14.38, 14.39, 14.4, 14.4, 14.41, 14.42, 14.43, 14.44, 14.45, 14.46, 14.47, 14.47, 14.48, 14.49, 14.5, 14.51, 14.52, 14.53, 14.53, 14.54, 14.55, 14.56, 14.57, 14.58, 14.59, 14.59, 14.6, 14.61, 14.62, 14.63, 14.64, 14.65, 14.65, 14.66, 14.67, 14.68, 14.69, 14.7, 14.71, 14.71, 14.72, 14.73, 14.74, 14.75, 14.76, 14.76, 14.77, 14.78, 14.79, 14.8, 14.81, 14.82, 14.82, 14.83, 14.84, 14.85, 14.86, 14.87, 14.87, 14.88, 14.89, 14.9, 14.91, 14.92, 14.92, 14.93, 14.94, 14.95, 14.96, 14.97, 14.97, 14.98, 14.99, 15, 15.01, 15.02, 15.02, 15.03, 15.04, 15.05, 15.06, 15.07, 15.07, 15.08, 15.09, 15.1, 15.11, 15.12, 15.12, 15.13, 15.14, 15.15, 15.16, 15.17, 15.17, 15.18, 15.19, 15.2, 15.21, 15.22, 15.22, 15.23, 15.24, 15.25, 15.26, 15.26, 15.27, 15.28, 15.29, 15.3, 15.31, 15.31, 15.32, 15.33, 15.34, 15.35, 15.35, 15.36, 15.37, 15.38, 15.39, 15.39, 15.4, 15.41, 15.42, 15.43, 15.44, 15.44, 15.45, 15.46, 15.47, 15.48, 15.48, 15.49, 15.5, 15.51, 15.52, 15.52, 15.53, 15.54, 15.55, 15.56, 15.56, 15.57, 15.58, 15.59, 15.6, 15.6, 15.61, 15.62, 15.63, 15.64, 15.64, 15.65, 15.66, 15.67, 15.68, 15.68, 15.69, 15.7, 15.71, 15.72, 15.72, 15.73, 15.74, 15.75, 15.76, 15.76, 15.77, 15.78, 15.79, 15.8, 15.8, 15.81, 15.82, 15.83, 15.84, 15.84, 15.85, 15.86, 15.87, 15.87, 15.88, 15.89, 15.9, 15.91, 15.91, 15.92, 15.93, 15.94, 15.95, 15.95, 15.96, 15.97, 15.98, 15.98, 15.99};

// 227系500番台 東洋IGBT
/*float sequence_accl[][7] = {
    {0, 1, 0, 1045, 1045, 0, 0},
    {42, 0, 0, 9, 9, 0, 0},
    {120, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 1045, 1045, 0, 0},
    {42, 0, 0, 9, 9, 0, 0},
    {120, 0, 0, 1, 1, 0, 0}
};*/

// 223系5000番台 三菱IGBT
/*float sequence_accl[][7] = {
    {0, 1, 2, 480, 1700, 0.01, 0},
    {20, 1, 2, 760, 1300, 0.01, 0},
    {45, 1, 2, 1300, 1300, 0.01, 0},
    {60, 0, 0, 5, 5, 0, 0},
    {63, 0, 0, 3, 3, 0, 0},
    {65, 0, 1, 3, 3, 0, 0},
    {70, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 2, 480, 1700, 0.01, 0},
    {20, 1, 2, 760, 1300, 0.01, 0},
    {45, 1, 2, 1300, 1300, 0.01, 0},
    {60, 0, 0, 5, 5, 0, 0},
    {63, 0, 0, 3, 3, 0, 0},
    {65, 0, 1, 3, 3, 0, 0},
    {70, 0, 0, 1, 1, 0, 0}
};*/

/*float sequence_accl[][7] = {
    {0, 1, 0, 740, 740, 0, 0},
    {23, 1, 0, 740, 700, 0, 0},
    {43, 1, 0, 700, 1800, 0, 0},
    {54, 0, 1, 3, 3, 0, 0},
    {57, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 200, 200, 0, 0},
    {4, 1, 0, 740, 740, 0, 0},
    {28, 1, 0, 740, 700, 0, 0},
    {54, 1, 0, 700, 1700, 0, 0},
    {68, 0, 1, 3, 3, 0, 0},
    {73, 0, 0, 1, 1, 0, 0}
};*/

// 京急1000系 シーメンスGTO
float sequence_accl[][7] = {
    {0, 1, 0, 175, 175, 0, 0},
    {0.7, 1, 0, 196, 196, 0, 0},
    {1.4, 1, 0, 223, 223, 0, 0},
    {2, 1, 0, 233, 233, 0, 0},
    {2.6, 1, 0, 262, 262, 0, 0},
    {3.2, 1, 0, 294, 294, 0, 0},
    {3.8, 1, 0, 311, 311, 0, 0},
    {4.5, 1, 0, 350, 350, 0, 0},
    {5.2, 1, 0, 400, 400, 0, 0},
    {24, 0, 0, 18, 18, 0, 0},
    {26, 0, 0, 15, 15, 0, 0},
    {30, 0, 0, 12, 12, 0, 0},
    {36, 0, 0, 9, 9, 0, 0},
    {44, 0, 0, 7, 7, 0, 0},
    {56, 0, 0, 5, 5, 0, 0},
    {58, 0, 1, 3, 3, 0, 0},
    {80, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 400, 400, 0, 0},
    {22, 0, 0, 18, 18, 0, 0},
    {26, 0, 0, 15, 15, 0, 0},
    {30, 0, 0, 12, 12, 0, 0},
    {35, 0, 0, 9, 9, 0, 0},
    {42, 0, 0, 7, 7, 0, 0},
    {62, 0, 0, 5, 5, 0, 0},
    {70, 0, 1, 3, 3, 0, 0},
    {80, 0, 0, 1, 1, 0, 0}
};

// 鉄道唱歌
/*float sequence_accl[][7] = {
    {0, 1, 0, 784, 784, 0, 0},
    {7, 1, 0, 880, 880, 0, 0},
    {8, 1, 0, 988, 988, 0, 0},
    {15, 1, 0, 880, 880, 0, 0},
    {16, 1, 0, 784, 784, 0, 0},
    {23, 1, 0, 659, 659, 0, 0},
    {24, 1, 0, 587, 587, 0, 0},
    {32, 1, 0, 659, 659, 0, 0},
    {36, 1, 0, 587, 587, 0, 0},
    {39, 1, 0, 659, 659, 0, 0},
    {40, 1, 0, 784, 784, 0, 0},
    {44, 1, 0, 988, 988, 0, 0},
    {48, 1, 0, 880, 880, 0, 0},
    {52, 1, 0, 988, 988, 0, 0},
    {55, 1, 0, 880, 880, 0, 0},
    {56, 1, 0, 784, 784, 0, 0},
    {64, 0, 0, 3, 3, 0, 0},
    {70, 0, 1, 3, 3, 0, 0},
    {80, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 784, 784, 0, 0},
    {8, 1, 0, 880, 880, 0, 0},
    {9, 1, 0, 988, 988, 0, 0},
    {12, 1, 0, 880, 880, 0, 0},
    {16, 1, 0, 988, 988, 0, 0},
    {20, 1, 0, 784, 784, 0, 0},
    {24, 1, 0, 659, 659, 0, 0},
    {25, 1, 0, 587, 587, 0, 0},
    {28, 1, 0, 659, 659, 0, 0},
    {32, 1, 0, 587, 587, 0, 0},
    {40, 1, 0, 659, 659, 0, 0},
    {41, 1, 0, 784, 784, 0, 0},
    {48, 1, 0, 880, 880, 0, 0},
    {49, 1, 0, 988, 988, 0, 0},
    {56, 1, 0, 880, 880, 0, 0},
    {57, 1, 0, 784, 784, 0, 0},
    {64, 0, 0, 3, 3, 0, 0},
    {70, 0, 1, 3, 3, 0, 0},
    {80, 0, 0, 1, 1, 0, 0}
};*/

// ファミリーマート入店音
/*float sequence_accl[][7] = {
    {0, 1, 0, 494, 494, 0, 0},
    {2, 1, 0, 392, 392, 0, 0},
    {4, 1, 0, 294, 294, 0, 0},
    {6, 1, 0, 392, 392, 0, 0},
    {8, 1, 0, 440, 440, 0, 0},
    {10, 1, 0, 587, 587, 0, 0},
    {14, 1, 0, 294, 294, 0, 0},
    {16, 1, 0, 440, 440, 0, 0},
    {18, 1, 0, 494, 494, 0, 0},
    {20, 1, 0, 440, 440, 0, 0},
    {22, 1, 0, 294, 294, 0, 0},
    {24, 1, 0, 392, 392, 0, 0},
    {32, 0, 0, 3, 3, 0, 0},
    {46, 0, 1, 3, 3, 0, 0},
    {60, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 392, 392, 0, 0},
    {8, 1, 0, 294, 294, 0, 0},
    {10, 1, 0, 440, 440, 0, 0},
    {12, 1, 0, 494, 494, 0, 0},
    {14, 1, 0, 440, 440, 0, 0},
    {16, 1, 0, 294, 294, 0, 0},
    {18, 1, 0, 587, 587, 0, 0},
    {22, 1, 0, 440, 440, 0, 0},
    {24, 1, 0, 392, 392, 0, 0},
    {26, 1, 0, 294, 294, 0, 0},
    {28, 1, 0, 392, 392, 0, 0},
    {30, 1, 0, 494, 494, 0, 0},
    {32, 0, 0, 3, 3, 0, 0},
    {46, 0, 1, 3, 3, 0, 0},
    {60, 0, 0, 1, 1, 0, 0}
};*/

// 東武30000系 東芝IGBT
/*float sequence_accl[][7] = {
    {0, 1, 0, 1000, 1000, 0, 4.0},
    {16, 1, 0, 1000, 1000, 0, 0},
    {102, 0, 0, 5, 5, 0, 0},
    {116, 0, 0, 3, 3, 0, 0},
    {124, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 1000, 1000, 0, 4.0},
    {16, 1, 0, 1000, 1000, 0, 0},
    {102, 0, 0, 5, 5, 0, 0},
    {116, 0, 0, 3, 3, 0, 0},
    {124, 0, 0, 1, 1, 0, 0}
};*/

/*float sequence_accl[][7] = {
    {0, 1, 0, 10000, 10000, 0, 0},
    {100, 0, 0, 1, 1, 0, 0}
};
float sequence_decl[][7] = {
    {0, 1, 0, 10000, 10000, 0, 0},
    {100, 0, 0, 1, 1, 0, 0}
};*/

float sequence_arr[32][7];
unsigned int sequence_accl_len = LEN(sequence_accl);
unsigned int sequence_decl_len = LEN(sequence_decl);
unsigned int sequence_arr_len = 0;

// データ形式 [開始しきい値, モード(0: 同期モード, 1: 非同期モード, 2: 中立モード), キャリアタイプ(0: 三角波, 1: 広域, 2: ランダム, 4: 重畳, 6: ランダム+重畳), 同期モードの場合はパルスモード、非同期モードの場合は開始周波数, 非同期モードの場合は終了周波数]

float phase_u = 0;     // 変調波の位相(モーター用)
float async_phase = 0; // 非同期モード時の搬送波の位相
float async_random_phase = 0;  // 非同期モード時の搬送波のランダム位相
float async_superimposed_phase = 0;    // 非同期モード時の搬送波の重畳位相
unsigned int i = 0;
unsigned int j = 0;
unsigned long t = 0;
unsigned int random_index = 0;
float phase_v_add = (float)ARR_LEN * 2.0 / 3.0;
float phase_w_add = (float)ARR_LEN * 1.0 / 3.0;
float sampling_freq = 1.0 / fs;

bool timer_callback(repeating_timer_t *rt){
    t++;
    random_index++;
    if(random_index >= ARR_LEN){
        random_index = 0;
    }
    unsigned char motor_on_flag = 1;    // モーターのONフラグ

    float accl_buf = accl;
    accl = adc_accl;

    /*if(t < 5 * fs){
        accl = 2;
    }
    else if (t < 25 * fs){
        accl = 5;
    }
    else if (t < 30 * fs){
        accl = 0;
    }
    else if (t < 50 * fs){
        accl = -5;
    }
    else {
        accl = -2;
    }*/
    if(accl >= 0 && accl_buf < 0){
        sequence_arr_len = sequence_accl_len;
        for(i = 0; i < sequence_arr_len; i++){
            for(j = 0; j < 7; j++){
                sequence_arr[i][j] = sequence_accl[i][j];
            }
        }
    }
    else if(accl < 0 && accl_buf >= 0){
        sequence_arr_len = sequence_decl_len;
        for(i = 0; i < sequence_arr_len; i++){
            for(j = 0; j < 7; j++){
                sequence_arr[i][j] = sequence_decl[i][j];
            }
        }
    }

    modulated_freq += accl * sampling_freq; // 変調波周波数(モーターの周波数)
    if (accl == 0) {
        // 加速度0の場合は徐々に減速するので周波数を徐々に落とす
        modulated_freq -= 4.0 * sampling_freq;
    }
    if(modulated_freq < 0){
        modulated_freq = 0;
        motor_on_flag = 0;
    }
    // 位相算出
    phase_u += modulated_freq * (float)ARR_LEN * sampling_freq;
    while (phase_u >= ARR_LEN){
      phase_u -= (float)ARR_LEN;
    }
    float phase_v = phase_u + phase_v_add;
    float phase_w = phase_u + phase_w_add;
    if (phase_v >= ARR_LEN){
      phase_v -= (float)ARR_LEN;
    }
    if (phase_w >= ARR_LEN){
      phase_w -= (float)ARR_LEN;
    }
    // サイン波形算出
    int sin_u = sin_arr[(unsigned int)phase_u % ARR_LEN];
    int sin_v = sin_arr[(unsigned int)phase_v % ARR_LEN];
    int sin_w = sin_arr[(unsigned int)phase_w % ARR_LEN];

    /*if (sin_u >= 0){
        sin_u = min(sin_u + 32, 511);
    }*/

    // キャリア波形の初期化(電圧を出さない)
    int carrier_u = sin_u;
    int carrier_v = sin_v;
    int carrier_w = sin_w;
    // シーケンス番号選択処理
    unsigned int sequence_index = sequence_arr_len - 1;
    for (i = 0; i < sequence_arr_len; i++){
        if (modulated_freq < sequence_arr[i][0]){
            sequence_index = i - 1;
            break;
        }
    }
    if (sequence_arr[sequence_index][1] == 0){
        // 同期モード
        pulse_mode = sequence_arr[sequence_index][3];   // パルスモード
        /*if (pulse_mode >= 9 && pulse_mode <= 17){
            pulse_mode += 4;
        }*/
        if (pulse_mode == 1) {
            carrier_u = 0;
            carrier_v = 0;
            carrier_w = 0;
        }
        else if (sequence_arr[sequence_index][2] == 0){
            carrier_u = tri_arr[(unsigned int)(phase_u * (float)(pulse_mode)) % ARR_LEN];
            /*if (((pulse_mode - 1) / 2) % 2 != 0){
                carrier_u *= -1;
            }*/
            carrier_v = carrier_u;
            carrier_w = carrier_u;
            /*if (pulse_mode >= 13 && pulse_mode <= 21){
                int pulse_cut_level = sin_arr[(unsigned int)((float)(ARR_LEN) / (float)(pulse_mode) * (((float)(pulse_mode) - 5.0) / 12.0 + 1.5)) % ARR_LEN];
                
                if (sin_u >= 0){
                    if (sin_u < pulse_cut_level){
                        sin_u = 0;
                    }
                }
                else{
                    if (-sin_u < pulse_cut_level){
                        sin_u = 0;
                    }
                }
                if (sin_v >= 0){
                    if (sin_v < pulse_cut_level){
                        sin_v = 0;
                    }
                }
                else{
                    if (-sin_v < pulse_cut_level){
                        sin_v = 0;
                    }
                }
                if (sin_w >= 0){
                    if (sin_w < pulse_cut_level){
                        sin_w = 0;
                    }
                }
                else{
                    if (-sin_w < pulse_cut_level){
                        sin_w = 0;
                    }
                }
                sin_u = sin_u * 3 / 2;
                sin_v = sin_v * 3 / 2;
                sin_w = sin_w * 3 / 2;
            }*/
        }
        else{
            // 広域パルスモード
            carrier_u = wide_arr[(unsigned int)phase_u % ARR_LEN];
            carrier_v = wide_arr[(unsigned int)phase_v % ARR_LEN];
            carrier_w = wide_arr[(unsigned int)phase_w % ARR_LEN];
            sin_u = (sin_u >= 0) * (ARR_LEN - 1) - ARR_LEN / 2;
            sin_v = (sin_v >= 0) * (ARR_LEN - 1) - ARR_LEN / 2;
            sin_w = (sin_w >= 0) * (ARR_LEN - 1) - ARR_LEN / 2;
        }
    }
    else if (sequence_arr[sequence_index][1] == 1){
        // 非同期モード
        float carrier_start_freq = sequence_arr[sequence_index][3];   // 搬送波の開始周波数
        carrier_freq = carrier_start_freq;                       // 搬送波の周波数(スイッチング周波数)
        if (sequence_index < sequence_arr_len - 1){
            float carrier_end_freq = sequence_arr[sequence_index][4]; // 搬送波の終了周波数
            float modulated_start_freq = sequence_arr[sequence_index][0];     // 変調波の開始周波数
            float modulated_end_freq = sequence_arr[sequence_index + 1][0];   // 変調波の終了周波数
            carrier_freq += 1.0 / (modulated_end_freq - modulated_start_freq) * (carrier_end_freq - carrier_start_freq) * (modulated_freq - modulated_start_freq);
        }
        async_phase += carrier_freq * (float)ARR_LEN * sampling_freq;  // 非同期モードの位相
        if (async_phase >= ARR_LEN){
            async_random_phase = rand_arr[random_index];
            while (async_phase >= ARR_LEN){
                async_phase -= (float)ARR_LEN;
            }
        }
        
        
        float async_custom_phase = async_phase;
        if (sequence_arr[sequence_index][5] > 0){
            // ランダム変調
            async_custom_phase += async_random_phase * sequence_arr[sequence_index][5];
        }
        if (sequence_arr[sequence_index][6] >= 1.0){
            // 高周波重畳の位相
            async_superimposed_phase += carrier_freq * (float)ARR_LEN * sampling_freq / (sequence_arr[sequence_index][6] * 2.0);
            if (async_superimposed_phase >= ARR_LEN){
                while (async_superimposed_phase >= ARR_LEN){
                    async_superimposed_phase -= (float)ARR_LEN;
                }
            }
            // 高周波重畳
            sin_u *= (sin_arr[(unsigned int)(async_superimposed_phase) % ARR_LEN] >= 0) * 3 - 1;
            sin_v *= (sin_arr[(unsigned int)(async_superimposed_phase) % ARR_LEN] >= 0) * 3 - 1;
            sin_w *= (sin_arr[(unsigned int)(async_superimposed_phase) % ARR_LEN] >= 0) * 3 - 1;
        }
        carrier_u = tri_arr[(unsigned int)async_custom_phase % ARR_LEN];
        carrier_v = carrier_u;
        carrier_w = carrier_u;
    }
    else {
        // 中立モード
        motor_on_flag = 0;
    }

    if (motor_on_flag == 1 && modulated_freq != 0) {
        // モータ運転
        if (accl == 0) {    // 加速度0で惰行、それ以外は力行
            // 力行から惰行への移行処理
            if (sequence_arr[sequence_index][1] == 0 && pulse_mode == 1) {
                // パルスモードが同期1パルスモードの場合は3パルスにする
                carrier_u = tri_arr[(unsigned int)(phase_u * 3.0) % ARR_LEN];
                carrier_v = carrier_u;
                carrier_w = carrier_u;
            }
            // 力行から惰行になったときは電圧を徐々に下げる
            voltage -= 2.0 * sampling_freq;
        }
        else {
            if (modulated_freq / 80.0 < voltage) {    // 電圧計算条件の場合分け
                // モータは力行
                voltage = modulated_freq / 80.0 + 0.1; // 力行の電圧計算
            }
            else {
                // 惰行から力行への移行処理
                if (sequence_arr[sequence_index][1] == 0 && pulse_mode == 1) {
                    // パルスモードが同期1パルスモードの場合は3パルスにする
                    carrier_u = tri_arr[(unsigned int)(phase_u * 3.0) % ARR_LEN];
                    carrier_v = carrier_u;
                    carrier_w = carrier_u;
                }
                // 惰行から力行になったときは電圧を徐々に上げる
                voltage += 2.0 * sampling_freq;
            }
        }

        if (voltage > 1.0) {
            voltage = 1.0;
        }
        char pwm_u = 0;
        char pwm_v = 0;
        char pwm_w = 0;
        if (voltage > 0) {
            pwm_u = sin_u * voltage > carrier_u;
            pwm_v = sin_v * voltage > carrier_v;
            pwm_w = sin_w * voltage > carrier_w;
        }
        else {
            voltage = 0;
        }
        // syn_uv, syn_vw, syn_wu をデジタル出力する
        gpio_put(GPIO_U, pwm_u);
        gpio_put(GPIO_V, pwm_v);
        gpio_put(GPIO_W, pwm_w);
        gpio_put(GPIO_SD, 1);
    }
    else {
        // モータ停止
        gpio_put(GPIO_U, 0);
        gpio_put(GPIO_V, 0);
        gpio_put(GPIO_W, 0);
        gpio_put(GPIO_SD, 0);
    }
    return 1;
}

int main(){
    stdio_init_all();

    set_sys_clock_khz(250000, true);    // 動作クロック設定

    static repeating_timer_t timer;

    /*
    GPIO初期化処理
    */

    // GPIOを出力に設定
    gpio_init(GPIO_U);
    gpio_set_dir(GPIO_U, GPIO_OUT);
    gpio_init(GPIO_V);
    gpio_set_dir(GPIO_V, GPIO_OUT);
    gpio_init(GPIO_W);
    gpio_set_dir(GPIO_W, GPIO_OUT);
    gpio_init(GPIO_SD);
    gpio_set_dir(GPIO_SD, GPIO_OUT);
    gpio_init(GPIO_SD);

    // GPIOを入力に設定
    //gpio_init(GPIO_PLS);
    //gpio_set_dir(GPIO_PLS, GPIO_IN);
    

    for(i = 0; i <= 7; i++){
        gpio_init(i);
        gpio_set_dir(i, GPIO_OUT);
        gpio_put(i, 0);
    }
    for(i = 12; i <= 22; i++){
        gpio_init(i);
        gpio_set_dir(i, GPIO_OUT);
        gpio_put(i, 0);
    }
    /*for(i = 26; i <= 28; i++){
        gpio_init(i);
        gpio_set_dir(i, GPIO_OUT);
        gpio_put(i, 0);
    }*/
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    gpio_put(25, 1);

    adc_init();
    adc_gpio_init(ADC0_PIN);                //ADC0(GPIO26)の端子設定
    adc_select_input(0);                    

    // リセットパルスを出力
    /*gpio_put(GPIO_CLR, 0);
    sleep_ms(1000);
    gpio_put(GPIO_CLR, 1);
    sleep_ms(10);
    gpio_put(GPIO_CLR, 0);*/

    sequence_arr_len = sequence_accl_len;
    for(i = 0; i < sequence_arr_len; i++){
        for(j = 0; j < 5; j++){
            sequence_arr[i][j] = sequence_accl[i][j];
        }
    }

    add_repeating_timer_us(-1000000 / fs, &timer_callback, NULL, &timer);
    // gpio_set_irq_enabled_with_callback(GPIO_PLS, GPIO_IRQ_EDGE_FALL, true, gpio_interrupt_callback);
    while(1){
        gpio_put(25, 1);
        adc_val = (int)(adc_read()) / 342 - 6;

        adc_accl = (float)(adc_val); // * 2.0;
        if(adc_accl > -0.1 && adc_accl < 0.1){
            adc_accl = 0;
        }
        sleep_ms(100);
        gpio_put(25, 0);
        sleep_ms(100);
    }
}

製作した基板

メインコントローラ

ゲートドライブユニット

IGBTユニット

直流電源ユニット

回路図

ゲートドライブユニット回路図

IGBTモジュール回路図

直流電源ユニット回路図

使用した部品等

Raspberry Pi Pico

PIC16F1827

放熱穴付アルミケース

 

デモ

京急1000形シーメンスGTO(ドレミファインバータ)を再現しています。