SSブログ

macOSからPi Picoを使う - その5 [Pi Pico]

Pi Picoの持っているPWMが本家Raspberry Piよりベースクロックが高いのでアナログにしたいとき外部回路(主にローパス)が楽になる。これは結構ありがたい。

こないだからsdkのマニュアルばっかり引いていて自分のコードを書いてないので、ここでPWMを試しておこう.,..

7.3  PWMの簡単なテスト

Pi Picoの基板ではGPIO#25がLEDに繋がっている。外に回路をつけるのはめんどくさいので、これでPWMを試してみる。

この基板のLEDをPWM変調してみよう。あまり難しい関数にしてもしょうがないので三角波で変調する。その周期を仮想端末からUSB経由で変えられるようにしよう。

一気に書いてしまうと
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

static uint     ledgpio = 25;   //  GPIO number of LED on board
static uint     wrap = 500;     //  TOP register value

static uint16_t levelFromCount(int i);

int main() {
    stdio_init_all();
    
    gpio_set_function(ledgpio, GPIO_FUNC_PWM);
    uint    slice = pwm_gpio_to_slice_num(ledgpio);
    uint    chan = pwm_gpio_to_channel(ledgpio);
    pwm_set_wrap(slice, wrap);
    pwm_set_chan_level(slice, chan, 0);
    pwm_set_clkdiv(slice, 10.0);
    pwm_set_enabled(slice, true);
    uint64_t    usleep100 = 100;    //  sleep time for one stage in the period

    while (true) {
        int c = getchar_timeout_us(0);  //  check for input from USB
        if ((c != PICO_ERROR_TIMEOUT) && ('0' <= c)) {
            usleep100 = (uint64_t)((c - '0') * 100);
            printf("sleep time is set to %dusec\n", (int)usleep100);
        }
        int i;
        for (i = 0 ; i < wrap ; i ++) {
            pwm_set_chan_level(slice, chan, levelFromCount(i));
            sleep_us(usleep100);
        }
        for (i = wrap ; 0 < i ; i --) {
            pwm_set_chan_level(slice, chan, levelFromCount(i));
            sleep_us(usleep100);
        }
   }
    return 0;
}

static uint16_t levelFromCount(int i)
{
    return (uint16_t)(i * i / wrap);
}
コメントするまでもない簡単なループ。stdinから1キャラクタ入力があると、それを数字だとみなしてループ内部のスリープ時間を100〜900のμsecに変える。三角波の行って帰ってで、1000回ループを回るので0.1秒から0.9秒の周期になる。

levelFromCount()関数は「なんちゃって」ガンマ補正、というかウェーバー‐フェヒナー補正。

CMakeLists.txtは
cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)
project(test_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(pwmled
    pwmled.c
)

pico_enable_stdio_usb(pwmled 1)
pico_enable_stdio_uart(pwmled 0)

pico_add_extra_outputs(pwmled)

target_link_libraries(pwmled pico_stdlib hardware_pwm)
として、stdioをUSBに割り当てて、PWMのモジュールをリンクする。

動作させているところをYouTubeにあげた。
0528pwmled.jpg
やっぱり埋め込めない

やっていることは
uf2ファイルをコピー
$ cp pwmled.uf2 /Volumes/RPI-RP2/
ここで「ディスクの不正な取り出し」通知が出る
screenコマンドを入力
$ creen /dev/tty.usbmodem0000000000001 9600
screenコマンドから数字を入力するとそれに従って周期が変わる。
最後にUSB経由でリセット(BOOTSELブート)。
$ bootselBoot 
これだけ。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。