#author("2022-10-07T14:17:34+09:00","default:okada","okada") #author("2022-10-13T09:22:17+09:00","default:okada","okada") *Arduino Tips [#ad374f50] RIGHT:更新日&lastmod(); RIGHT:作成日:2022年10月5日 **インストール直後の設定画面で「OK」が押せない [#n35dbc4f] Arduinoインストール後、File→Preferencesで「OK」ボタンが、グレーアウトしている。有効にするには一番上の「Skechbook location」の「BROESE」ボタンを押して設定すると「OK」ボタンが押せるようになる。 &ref("./Preferences設定.png"); **シリアルデータの受信 [#lc39daef] デバッグ等でArduino IDEのシリアルモニタからデータを送信するようなときに使用する。 -数字データをデリミタで複数送る(例3:1500) -Serial.available()は受信バッファにあるデータの数を返す -Serial.parseInt()は数値データをAscll文字(a,b,:)まで読んで数値に変換。読込位置も読み込んだところまで進めるみたい -Serial.read()は1バイト読みこむ ***サンプル [#q8cc4e01] -seroal_recive.ino -serial_recive.ino //シリアルモニタから送信されたデータを受信してシリアルモニタに表示 // 例)3:1500 //受信データ格納配列 int data1[3] = {0, 0, 0}; int data2[3] = {0, 0, 0}; void reive_data(){ int in_data; if ( Serial.available() > 0){//入力がはいればを処理 delay(10); //データを全て受信するまで待つ(値は適当) in_data = Serial.parseInt(); data1[0] = in_data; char delimiter = Serial.read(); in_data = Serial.parseInt(); //デリミタをチェックすることで、「送信」ボタンやEnterだけ押された //とき無視する。正常データの場合も最後に「LF」が入り、ルーチンが2回 //周り「LF」のみの処理を行うので困る if (delimiter == ':'){//デリミタが「:」なら処理 data1[1] = in_data; //行末の「送信」ボタンまたはEnter入力時の「LF」を読み込んで捨てる char dummy = Serial.read(); Serial.print(data1[0]); Serial.print( delimiter ); Serial.print(delimiter, DEC); Serial.print( "====>"); Serial.println(data1[1]); } } } void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: reive_data(); } ***実行結果 [#wf25876f] &ref("./シリアル.png"); -上記の入力の場合は「3:1500」の後ろに「LF」が付加される。これは「送信」ボタンやEnterでデータを送るため、そのコードが付く。 **多相のパルス生成 [#k51f21ab] サーボモータを複数使用するためなどに利用できそうな多相パルスを作成。 ***プログラム [#r1769d99] -周期:20ms -チャネル数:8 -起動時の全チャネルのパルス幅は1000us -シリアル入力からパルス幅を指定(10us程度の分解能)して入力 --例 2:2000 → CH2のパルス幅を2000usに指定 -出力CH0:PIN5 → CH7:PIN12 ***ソース [#r384cae8] -mphasepuls-test.ino // 多相パルス発生プログラム // 8相PIN5-12 // #define CH0_PIN 5 #define CH1_PIN 6 #define CH2_PIN 7 #define CH3_PIN 8 #define CH4_PIN 9 #define CH5_PIN 10 #define CH6_PIN 11 #define CH7_PIN 12 //シリアルからパルス幅の設定チャンネル int sel_ch; //0-7 //パルス幅(us) int pw[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000}; //1ms int in_data1; int in_data2; //PWM作成 void mk_pwm(){ //20ms周期に入るとき全てのチャンネルをHighにする digitalWrite( CH0_PIN, HIGH ); digitalWrite( CH1_PIN, HIGH ); digitalWrite( CH2_PIN, HIGH ); digitalWrite( CH3_PIN, HIGH ); digitalWrite( CH4_PIN, HIGH ); digitalWrite( CH5_PIN, HIGH ); digitalWrite( CH6_PIN, HIGH ); digitalWrite( CH7_PIN, HIGH ); int i = 0; while ( i < 1920){ // シリアルチェックで分を引く delayMicroseconds( 7 ); //全体で10usになるように設定 int j = i * 10; if (pw[0] == j){ digitalWrite( CH0_PIN, LOW ); } if (pw[1] == j){ digitalWrite( CH1_PIN, LOW ); } if (pw[2] == j){ digitalWrite( CH2_PIN, LOW ); } if (pw[3] == j){ digitalWrite( CH3_PIN, LOW ); } if (pw[4] == j){ digitalWrite( CH4_PIN, LOW ); } if (pw[5] == j){ digitalWrite( CH5_PIN, LOW ); } if (pw[6] == j){ digitalWrite( CH6_PIN, LOW ); } if (pw[7] == j){ digitalWrite( CH7_PIN, LOW ); } i++; } } //シリアルポートからパルス幅をusで入力 (例 ch1:800) //PWMの周期はこの命令のロス分を考慮 int serialReadAsPw() { if ( Serial.available() > 0){ delay(10); //データを全て受信するまで待つ(値は適当) in_data1 = Serial.parseInt(); char delimiter = Serial.read(); in_data2 = Serial.parseInt(); if (delimiter == ':'){//デリミタが「:」なら処理 pw[in_data1] = in_data2; } } } void setup() { // put your setup code here, to run once: Serial.begin( 9600); pinMode( CH0_PIN, OUTPUT ); pinMode( CH1_PIN, OUTPUT ); pinMode( CH2_PIN, OUTPUT ); pinMode( CH3_PIN, OUTPUT ); pinMode( CH4_PIN, OUTPUT ); pinMode( CH5_PIN, OUTPUT ); pinMode( CH6_PIN, OUTPUT ); pinMode( CH7_PIN, OUTPUT ); } void loop() { // put your main code here, to run repeatedly: serialReadAsPw(); mk_pwm(); } ***実行結果 [#c3aeb86c] −ロジックアナライザの出力 --シリアルからの入力 +0:500 +2:2000 +3:3000 +4:4000 +5:5000 +6:6000 +7:7000 &ref("./多相パルス.png");