/****************************/ /* PWM出力のテスト */ /****************************/ // USB(Serial)で通信 // Serial1でPWM値の変化を出力 // PWM周波数は500Hz, 8bit分解能 // タイトル const char ttl_msg[] = "# Pico PWM Test (2023-02-16)"; const char *inp_msg[] = { // inp_modeで区分して出力 "# PWM Port >", // 0:PWMポート番号入力 "# PWM Data (0...255) >", // 1:PWMデータ入力 }; // LED点滅 #define LED_PORT 25 // 1出力でLEDオン /****************************/ /* 送受データ */ /****************************/ /***** 送信データ *****/ char tx_str[64]; // 送信文字列 /***** シリアル1行入力 *****/ #define RXBF_SIZ 32 // 文字バッファ文字数 char rx_bff[RXBF_SIZ+1]; // 受信文字バッファ (+null) byte f_rxok; // 受信データありフラグ /***** シリアル1行受信 *****/ // CRでターミネート f_rxokを1に // エコーバックありで // なし→BSで1文字戻す void rxbff(void) { static byte cnt = 0; // 受信文字数 char c; if(Serial.available()){ // 受信データあり if(f_rxok == 0){ // 前データ受信処理した c = Serial.read(); // 1文字読み出し if(c == '\r'){ // CR? rx_bff[cnt] = '\0'; // nullを最後に Serial.println(); // 改行 f_rxok = 1; // 受信成功 cnt = 0; // 最初から } else if(c == '\x08'){ // BS? if(cnt > 0){ cnt--; // 1文字戻す Serial.print("\b \b"); // BS,space,BS } } else{ // 文字 if((cnt < RXBF_SIZ) && // バッファサイズ内 (isprint(c))){ // 表示可能文字0x20~0x7E Serial.write(c); // エコーバック rx_bff[cnt] = c; // バッファに入れる cnt++; // 1文字進める } } } } } /*********************************/ /* 制御実行処理 */ /*********************************/ // 制御用データ int inp_mode; // 入力モード // 0 : PWMポート番号 // 1 : PWMデータ int pwm_port; // PWMポート番号 int pwm_data; // PWM設定値 8bitデータ int tm_100ms; // 100ms ダウンカウントタイマー /***** 制御実行区分 *****/ byte j_exc; // 実行区分 #define J_DATAIN 1 // データ入力 #define J_SCAN 3 // PWMスキャン /***** スタンバイ *****/ // 最初のCR入力を待ってタイトル表示 void jstby(void) { if(f_rxok){ // CR入力待ち f_rxok = 0; Serial.println(); // 改行 Serial.println(ttl_msg); // タイトル出力 j_exc++; // next exc } } /***** 数値入力 入力項目表示 *****/ // inp_modeで入力対象を変更 void jdatain(void) { Serial.print(inp_msg[inp_mode]); // 入力項目 j_exc++; // next exc } /***** 数値入力 データ入力処理 *****/ // PWMポート番号あるいはPWMデータ void jdatain1(void) { int d; if(f_rxok){ // CR入力待ち f_rxok = 0; if(strlen(rx_bff) == 0){ // CRだけ inp_mode = 0; // PWMポート入力に j_exc = J_DATAIN; // 戻してもう一度 } else{ // 文字入力あり d = atoi(rx_bff); // 数字に変換 if(inp_mode == 0){ // 0:PWMポート番号入力 pwm_port = d; analogWrite(pwm_port, 128); // PWM duty 50%出力 inp_mode++; // 次はデータ j_exc = J_DATAIN; } else{ // 1:PWMデータ入力 pwm_data = d; if(pwm_data >= 0){ // 0~プラスならPWM値セット analogWrite(pwm_port, pwm_data); // PWM出力 sprintf(tx_str, "PWM %2d %4d", pwm_port, pwm_data); Serial.println(tx_str); j_exc = J_DATAIN; // 繰り返し } else{ // マイナスなら連続可変へ Serial.println("Scan."); pwm_data = 1; // 1~254まで j_exc = J_SCAN; // 出力開始 } } } } } /***** PWM値連続可変 *****/ // 2秒サイクルで出力 void jscan(void) { analogWrite(pwm_port, pwm_data); // PWM出力 sprintf(tx_str, "%4d", pwm_data); Serial.println(tx_str); // USB Serial1.println(tx_str); // TX1 tm_100ms = 20; // 2秒タイマーセット j_exc++; // next exc } /***** PWM値連続可変 #1 *****/ // タイムアップで次データへ void jscan1(void) { byte bk = 0; if(f_rxok){ // CR入力で中断 f_rxok = 0; Serial.println("Break."); bk = 1; } if(tm_100ms == 0){ // タイムアップした pwm_data++; // PWM値を+1 if(pwm_data > 254){ // 1~254を出力完了? Serial.println("Finish."); bk = 1; // おわり } else{ // 時間待ち j_exc = J_SCAN; // PWM出力続行 } } if(bk){ // おわり inp_mode = 0; // PWMポート番号入力に j_exc = J_DATAIN; // 戻してもう一度 } } /********************************/ /* 制御実行テーブル */ /********************************/ /***** 制御実行 *****/ void (*jexc[])(void)={ jstby, // 0:スタンバイ jdatain, // * 1:データ入力 jdatain1, // 2 jscan, // * 3:連続PWM出力 jscan1, // 4 }; /****************************/ /* SETUP */ /****************************/ /***** SETUP *****/ void setup() { Serial.begin(9600); // USB TX,RX Serial1.begin(9600); // TX1 pinMode(LED_PORT, OUTPUT); // LED } /****************************/ /* LOOP */ /****************************/ /***** LOOP *****/ void loop() { byte f_led = 0; // LED点滅用 uint32_t t0, t1; // タイマー t0 = millis(); while(1){ t1 = millis(); if((t1 - t0) >= 100){ // 0.1秒経過? t0 = t1; f_led ^= 1; // LED トグル gpio_put(LED_PORT, f_led); // LED出力 if(tm_100ms) tm_100ms--; // 100ms ダウンカウントタイマー } rxbff(); // 1行受信処理 jexc[j_exc](); // 制御実行区分で } } /*==== end of "pwm_serial_in1.ino" ====*/