iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
Modern Web

你渴望連結嗎?將 Web 與硬體連上線吧!系列 第 17

D16 - 「脈衝×寬度×調變」

  • 分享至 

  • xImage
  •  

本系列文已改編成書「Arduino 自造趣:結合 JavaScript x Vue x Phaser 輕鬆打造個人遊戲機」,本書改用 Vue3 與 TypeScript 全面重構且加上更詳細的說明,

在此感謝 iT 邦幫忙、博碩文化與編輯小 p 的協助,歡迎大家前往購書,鱈魚在此感謝大家 (。・∀・)。

若想 DIY 卻不知道零件去哪裡買的讀者,可以參考此連結 。( •̀ ω •́ )✧


這個章節要開始建立「PWM 輸出視窗」。

何謂 PWM

名為「脈衝寬度調變」(Pulse-width modulation)。PWM 本質上算是一種數位訊號,但是透過調整頻寬的方式,可以產生類似「類比訊號」的效果,是一種非常方便的技術,被大量應用在調速、通訊等等場合。

更詳細的說明可以參考以下連結:
PWM 脈衝寬度調變

建立 PWM 輸出視窗

內容大多可復用先前數位、類比功能視窗,所以過程大同小異 ∠( ᐛ 」∠)_

window-example.vue 複製一份後改個名字,建立 window-analog-input.vue

src\components\window-pwm-output.vue

<template lang="pug">
base-window.window-pwm-output(
  :pos='pos',
  header-icon-color='light-green-4',
  body-class='c-col p-20px pt-20px',
  title='PWM 輸出功能'
)
</template>

<style lang="sass">
.window-pwm-output
  width: 300px
  height: 400px
</style>

<script>
import BaseWindow from '@/components/base-window.vue';
import mixinWindow from '@/mixins/mixin-window';

export default {
  name: 'WindowPwmOutput',
  components: {
    'base-window': BaseWindow,
  },
  mixins: [mixinWindow],
  props: {},
  data() {
    return {};
  },
  computed: {},
  watch: {},
  created() {
    console.log(`[ ${this.$options.name} created ] id : `, this.id);
  },
  mounted() {},
  methods: {},
};
</script>

接著回到 app.vue,將右鍵選單內加入『新增「PWM 輸出視窗」』選項,並引入組件。

src\app.vue <template lang="pug">

.screen(@click='handleClick')
  // ...

	// 右鍵選單
  q-menu(context-menu, content-class='border-radius-s')
    q-list.min-w-260px
      q-item(@click='addWindow("window-digital-io")', clickable, v-close-popup)
        q-item-section
          | 新增「數位 I/O 視窗」
			q-item(@click='addWindow("window-analog-input")', clickable, v-close-popup)
        q-item-section
          | 新增「類比輸入視窗」
			q-item(@click='addWindow("window-pwm-output")', clickable, v-close-popup)
        q-item-section
          | 新增「PWM 輸出視窗」

src\app.vue <script>

// ...

import WindowDigitalIo from '@/components/window-digital-io.vue';
import WindowAnalogInput from '@/components/window-analog-input.vue';
import WindowPwmOutput from '@/components/window-pwm-output.vue';

export default {
  name: 'App',
  components: {
		'dialog-system-setting': DialogSystemSetting,
    
    'window-digital-io': WindowDigitalIo,
    'window-analog-input': WindowAnalogInput,
    'window-pwm-output': WindowPwmOutput,
  },
  // ...
};

加入視窗內容

一樣加入 base-select-pin.vue

src\components\window-pwm-output.vue <script>

import mixinWindow from '@/mixins/mixin-window';

import BaseWindow from '@/components/base-window.vue';
import BaseSelectPin from '@/components/base-select-pin.vue';

export default {
  name: 'WindowPwmOutput',
  components: {
    'base-window': BaseWindow,
    'base-select-pin': BaseSelectPin,
  },
  mixins: [mixinWindow],
  props: {},
  data() {
    return {};
  },
  computed: {},
  watch: {},
  created() {
    console.log(`[ ${this.$options.name} created ] id : `, this.id);
  },
  mounted() {},
  methods: {},
};

src\components\window-pwm-output.vue <template lang="pug">

base-window.window-pwm-output(
  :pos='pos',
  header-icon-color='light-green-4',
  body-class='c-col p-20px pt-20px',
  title='PWM 輸出功能'
)
  base-select-pin(color='light-green-4')

https://ithelp.ithome.com.tw/upload/images/20240118/20140213vnpYhD8h9U.png

接著便是提供腳位清單了,在 computed 增加 supportPins,提供支援 PWM 功能的腳位。

src\components\window-pwm-output.vue <script>

import { mapState } from 'vuex';

// ...

import { PinMode } from '@/script/utils/firmata.utils';
const { PWM } = PinMode;

export default {
  name: 'WindowPwmOutput',
  // ...
  computed: {
	...mapState({
      boardPins: (state) => state.board.info.pins,
    }),

    // 支援功能的腳位
    supportPins() {
      /** @type {PinInfo[]} */
      const boardPins = this.boardPins;

      return boardPins.filter((pin) =>
        pin.capabilities.some((capability) => PWM === capability.mode)
      );
    },
  },
  // ...
};

src\components\window-pwm-output.vue <template lang="pug">

base-window.window-pwm-output(
  :pos='pos',
  header-icon-color='light-green-4',
  body-class='c-col p-20px pt-20px',
  title='PWM 輸出功能'
)
  base-select-pin(:pins='supportPins', color='light-green-4')

D16 - PWM 輸出腳位 select options.gif

可以看到只有 Pin 3、5、6、9、10、11,比對一下 Uno 腳位,會注意到這些腳位數字旁邊都有個「~」符號,這些符號便是 PWM 功能的意思。

https://ithelp.ithome.com.tw/upload/images/20240118/20140213fcivqwWVav.png

儲存建立腳位

接下來依樣是儲存建立腳位的部分。

  • 增加 existPins 變數,儲存目前已建立腳位
  • 綁定 base-select-pin.vueselected 事件,接收被選擇的腳位。

src\components\window-pwm-output.vue <script>

/**
 * @typedef {import('@/types/type').PinInfo} PinInfo
 */

import { mapState } from 'vuex';

import mixinWindow from '@/mixins/mixin-window';

import BaseWindow from '@/components/base-window.vue';
import BaseSelectPin from '@/components/base-select-pin.vue';

import { PinMode } from '@/script/utils/firmata.utils';
const { PWM } = PinMode;

export default {
  name: 'WindowPwmOutput',
  // ...
  data() {
    return {
      /** @type {PinInfo[]} */
      existPins: [],
    };
  },
  // ...
  methods: {
    /** 新增腳位
     * @param {PinInfo} pin
     */
    addPin(pin) {
      if (!pin) return;

      this.$store.commit('window/addOccupiedPin', {
        id: this.id,
        pin,
      });

      this.existPins.push(pin);
    },
    /** 移除腳位
     * @param {PinInfo} pin
     */
    deletePin(pin) {
      if (!pin) return;

      this.$store.commit('window/deleteOccupiedPin', {
        id: this.id,
        pin,
      });

      const index = this.existPins.findIndex(
        (existPin) => existPin.number === pin.number
      );
      this.existPins.splice(index, 1);
    },

    /** 接收錯誤訊息 */
    handleErr(msg) {
      this.$q.notify({
        type: 'negative',
        message: msg,
      });
    },
  },
};

src\components\window-pwm-output.vue <template lang="pug">

base-window.window-pwm-output(
  :pos='pos',
  header-icon-color='light-green-4',
  body-class='c-col p-20px pt-20px',
  title='PWM 輸出功能'
)
  base-select-pin(
    :pins='supportPins',
    color='light-green-4',
    @selected='addPin',
    @err='handleErr'
  )

聰明的讀者們一定注意到了「這裡的步驟和數位、類比視窗都一樣」,所以大家也可以將這些重複內容抽出、建立 mixin。( ‧ ∀ ‧)ノ╰(‧ ∀ ‧ )

試試有沒有正常。

D16 - PWM 輸出視窗選擇腳位.gif

輕鬆愉快的完成 PWM 視窗,再來一樣進入建立控制組件環節。

總結

  • 成功建立 PWM 輸出視窗。
  • 引入 base-select-pin 組件,用於選擇腳位。
  • 儲存選擇腳位清單。

以上程式碼已同步至 GitLab,大家可以前往下載:

GitLab - D16


上一篇
D15 - 「類比×電壓×輸入」:建立控制組件
下一篇
D17 - 「脈衝×寬度×調變」:Arduino PWM 功能
系列文
你渴望連結嗎?將 Web 與硬體連上線吧!33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言