Raspberry Pi Pico で鉄道模型を動かす
(1) pico側に書き込んだスケッチ
#include <hardware/pwm.h>
void pico_analogWriteFreqRang(int pin, float freq, uint32_t rang)
// rang=[0,65535], freq > 125000000.0 / (rang + 1) / 256
// slice0: GP0, GP1, GP16, GP17
// slice1: GP2, GP3, GP18, GP19
// slice2: GP4, GP5, GP20, GP21
// slice3: GP6, GP7, GP22
// slice4: GP8, GP9, GP25
// slice5: GP10, GP11, GP26, GP27
// slice6: GP12, GP13, GP28
// slice7: GP14, GP15
// [註]sliceが同じものは、freqとrangは共通になる.
{
int slice_num = pwm_gpio_to_slice_num(pin);
float tmp = (rang + 1) * freq;
gpio_set_function(pin, GPIO_FUNC_PWM);
pwm_set_clkdiv(slice_num, 125000000.0 / tmp); // 256未満.
pwm_set_wrap(slice_num, rang);
}
void pico_analogWrite(int pin, uint32_t val)
{
int slice_num = pwm_gpio_to_slice_num(pin);
pwm_set_chan_level(slice_num, pin & 1, val);
pwm_set_enabled(slice_num, true);
}
void setup() { Serial.begin(115200); }
int prm_f0[4][4], prm_f1[16][4], prm_f2[3] = { A0, A1, A2 };
int prms[8] = { 4, 4, 1, 0, 1, 2, 1, 1 };
void loop()
{
int c = Serial.read(), ch, p[8], dir, i, j;
if (c < 0) { delay(3); }
if (0xf0 <= c && c <= 0xf7) {
j = prms[c - 0xf0];
for (i = 0; i < j; i++) {
while (Serial.available() < 1) {}
p[i] = Serial.read();
}
ch = p[0] & 63;
dir = (p[0] >> 6) & 3;
}
if (c == 0xf0 && 0 <= ch && ch <= 3) {
prm_f0[ch][0] = p[1]; pinMode(p[1], OUTPUT);
prm_f0[ch][1] = p[2]; pinMode(p[2], OUTPUT);
prm_f0[ch][2] = p[3]; pinMode(p[3], OUTPUT);
pico_analogWriteFreqRang(p[1], 100 * 1000, 255); // 100KHz
pico_analogWrite(p[1], 0);
digitalWrite(p[2], LOW);
digitalWrite(p[3], LOW);
}
if (c == 0xf1 && 0 <= ch && ch <= 15) {
prm_f1[ch][0] = p[1];
prm_f1[ch][1] = p[2]; pinMode(p[2], OUTPUT);
prm_f1[ch][2] = p[3]; pinMode(p[3], OUTPUT);
digitalWrite(p[2], LOW);
digitalWrite(p[3], LOW);
}
if (c == 0xf4 && 0 <= ch && ch <= 3) {
digitalWrite(prm_f0[ch][1], dir & 1);
digitalWrite(prm_f0[ch][2], (dir >> 1) & 1);
}
if (c == 0xf5 && 0 <= ch && ch <= 3) {
pico_analogWrite(prm_f0[ch][0], p[1]);
}
if (c == 0xf6 && 0 <= ch && ch <= 15) {
digitalWrite(prm_f1[ch][1], dir & 1);
digitalWrite(prm_f1[ch][2], (dir >> 1) & 1);
delay(prm_f1[ch][0] * 8); // max 2.0sec.
digitalWrite(prm_f1[ch][1], LOW);
digitalWrite(prm_f1[ch][2], LOW);
}
if (c == 0xf7 && 0 <= ch && ch <= 2) {
i = analogRead(prm_f2[ch]);
Serial.write((i >> 8) & 255);
Serial.write( i & 255);
}
}