pi picoでmicropython その40

# 概要
picoでmicropythonやってみた。
練習問題やってみた。

# 練習問題
俺言語インタープリタを拡張し、AMラジオを鳴らせ。

# 方針
?='abc'で、右項に'が来れば、ドレミを発振させる。
PWMを600kHzで使う。
GP17ピンに、銅線を繋ぐ。（アンテナ）
ラジオは、600kHzに、同調させる。

# ドレミのソースコード

```
10 ?='chhhgececcaceeeehegaq'
20 ?='aceehjhghgeeceeelhljq'
30 #=10

```

# サンプルコード

```
import random
import time
import sys
import utime
from machine import Pin, PWM
Ram = []
Lbf = 237
Bnd = 234
PC = 235
Ptr = 0
Cur = 0
Adr = 0
Adr2 = 0
Val = 0
C = 0
led = machine.Pin(25, machine.Pin.OUT)
adc = temp = machine.ADC(4)
pwm = PWM(Pin(17))
pwm.freq(600000)
def playTone(tone, tempo):
   h = 0
   w = 0
   if tone == 97:
      h = 466 / 32
      w = int(1000000 / 466)
   elif tone == 98:
      h = 493 / 32
      w = int(1000000 / 493)
   elif tone == 99:
      h = 523 / 32
      w = int(1000000 / 523)
   elif tone == 100:
      h = 554 / 32
      w = int(1000000 / 554)
   elif tone == 101:
      h = 587 / 32
      w = int(1000000 / 587)
   elif tone == 102:
      h = 622 / 32
      w = int(1000000 / 622)
   elif tone == 103:
      h = 659 / 32
      w = int(1000000 / 659)
   elif tone == 104:
      h = 698 / 32
      w = int(1000000 / 698)
   elif tone == 105:
      h = 739 / 32
      w = int(1000000 / 739)
   elif tone == 106:
      h = 783 / 32
      w = int(1000000 / 783)
   elif tone == 107:
      h = 830 / 32
      w = int(1000000 / 830)
   elif tone == 108:
      h = 880 / 32
      w = int(1000000 / 880)
   else:
      print(tone)
      h = 466 / 32
      w = int(1000000 / 466)
   while tempo > 0:
      tempo = tempo - 1
      if tone == 'q':
         utime.sleep_us(500000)
      else:
         for i in range(int(h)):
            pwm.duty_u16(30000)
            utime.sleep_us(w)
            pwm.duty_u16(0)
            utime.sleep_us(w)
def doremi(d):
   global Ptr
   while READB(Ptr) != d:
      playTone(READB(Ptr), 6)
      put(READB(Ptr))
      Ptr = Ptr + 1
def crlf():
   print()
def put(b):
   print(b, end = " ")
def putchar(b):
   c = chr(b)
   print(c, end = "")
def putl(pt, d):
   while READB(pt) != d:
      putchar(READB(pt))
      pt = pt + 1
   return pt
def putlp(d):
   global Ptr
   while READB(Ptr) != d:
      putchar(READB(Ptr))
      Ptr = Ptr + 1
def nxtln(pt):
   while READB(pt) != ord('\0'):
      pt = pt + 1
   pt = pt + 1
   return pt
def fndln():
   global Bnd, PC, Cur
   Cur = 0
   while Cur != READB(Bnd):
      if READB(Cur) == READB(PC):
         return True
      Cur = nxtln(Cur)
   return False
def fndln2():
   global Bnd, PC, Cur
   Cur = 0
   while Cur != READB(Bnd):
      if READB(Cur) > READB(PC):
         return True
      Cur = nxtln(Cur)
   return False
def WRITEB(adr, data):
   global Ram
   Ram[adr] = data
def READB(adr):
   global Ram
   v = Ram[adr]
   return v
def num():
   global Ptr
   if (48 <= READB(Ptr)) and (READB(Ptr) <= 57):
      return True
   else:
      return False
def getnm():
   global Ptr, Val
   if not(num()):
      return False
   n = 0
   while (num()):
      n *= 10
      ch = READB(Ptr)
      Ptr = Ptr + 1
      n += (ch - 48)
   Val = n
   return True
def getvr():# hidari
   global Ptr, Adr, PC, C
   C = READB(Ptr)
   if C == ord('a'):
      Adr = 230
   elif C == ord('#'):
      Adr = PC
   elif C == ord('b'):
      Adr = 231
   elif C == ord('c'):
      Adr = 232
   else:
      Adr = 230
def getvr2():
   global Ptr, Adr2, PC
   cc = READB(Ptr)
   if cc == ord('a'):
      Adr2 = 230
   elif cc == ord('#'):
      Adr2 = PC
   elif cc == ord('b'):
      Adr2 = 231
   elif cc == ord('c'):
      Adr2 = 232
   else:
      Adr2 = 230
def term():
   global Ptr, Val
   cc = READB(Ptr)
   val2 = Val
   Ptr = Ptr + 1
   factr()
   if cc == ord('*'):
      Val = val2 * Val
   elif cc == ord('+'):
      Val = val2 + Val
   elif cc == ord('-'):
      Val = val2 - Val
   elif cc == ord('/'):
      Val = val2 / Val
   elif cc == ord('%'):
      Val = val2 % Val
   elif cc == ord('='):
      if (val2 == Val):
         Val = 1
      else:
         Val = 0
   elif cc == ord('>'):
      if (val2 >= Val):
         Val = 1
      else:
         Val = 0
   else:
      if (val2 < Val):
         Val = 1
      else:
         Val = 0
def factr():# migi
   global Ptr, Val, Adr2
   if READB(Ptr) == ord('\0'):
      Val = 0
      return
   if getnm():
      return
   cc = READB(Ptr)
   if cc == ord('$'):# rnd
      r = random.random()
      Val = int(r * 10)
      Ptr = Ptr + 1
   elif cc == ord('?'):# input
      Val = int(input("?"))
      Ptr = Ptr + 1
   elif cc == ord('h'):# H
      tm = utime.localtime()
      Val = tm[3]
      Ptr = Ptr + 1
   elif cc == ord('m'):# m
      tm = utime.localtime()
      Val = tm[4]
      Ptr = Ptr + 1
   elif cc == ord('s'):# s
      tm = utime.localtime()
      Val = tm[5]
      Ptr = Ptr + 1
   elif cc == ord('l'):# adc
      v = adc.read_u16()
      v = v >> 7
      Val = v & 0xff
      Ptr = Ptr + 1
   else:
      getvr2()
      Val = READB(Adr2)
      Ptr = Ptr + 1
def expr():# migi
   global Ptr
   factr()# getval
   cc = READB(Ptr)
   while cc != ord('\0'):
      term()# enzan
      cc = READB(Ptr)
   Ptr = Ptr + 1
def ordr():# siki hyouka
   global Ptr, Val, C, Adr
   getvr()# hidari
   Ptr = Ptr + 2
   if READB(Ptr) == ord('"'):# print("")
      Ptr = Ptr + 1
      putlp(ord('"'))
   elif READB(Ptr) == ord("'"):# doremi
      Ptr = Ptr + 1
      doremi(ord("'"))
   elif READB(Ptr) == ord('!'):# crlf
      print()
   else:
      expr()# migi
      if C == ord('?'):
         put(Val)# print
      elif C == ord('l'):# led
         led.value(Val)
      elif C == ord('"'):# sleep
         time.sleep(Val)
      else:
         WRITEB(Adr, Val)# dainyuu
def run():
   global Bnd, Ptr, Lbf, Cur, PC, Ram
   for i in range(276):
      Ram.append(0)
   WRITEB(Bnd, 0)
   print("oregengo v1.5")
   while True:
      str = input("\n>")
      Ptr = Lbf
      for j in str:
         WRITEB(Ptr, ord(j))
         Ptr = Ptr + 1
      WRITEB(Ptr, ord('\0'))
      ima = 0
      Ptr = Lbf
      if not(getnm()):# dairect
         while True:
            ima = READB(PC)
            #print(ima)
            ordr()# siki hyouka
            if READB(PC) == 0 and ima == 0:
               break
            else:
               if READB(PC) == 0:
                  WRITEB(PC, ima)
               if READB(PC) == 1:
                  ima = 1
               if READB(PC) == 300:
                  sys.exit()
               if READB(PC) == ima:
                  if fndln2():
                     WRITEB(PC, READB(Cur))
                     Ptr = Cur + 2
                  else:
                     break
               else:
                  if fndln():
                     WRITEB(PC, READB(Cur))
                     Ptr = Cur + 2
                  else:
                     break
      else:
         if Val == 0:
            #print("#list")
            pt = 0
            while pt < READB(Bnd):
               put(READB(pt))
               pt = pt + 1
               pt = putl(pt, ord('\0'))
               crlf()
               pt = pt + 1
         else:# del insert append
            f = 0
            WRITEB(PC, Val)
            if fndln():
               #print("#del")
               src = nxtln(Cur)
               dst = Cur
               while src != READB(Bnd):
                  WRITEB(dst, READB(src))
                  dst = dst + 1
                  src = src + 1
               WRITEB(Bnd, dst)
            if fndln2():
               f = 1
            src = READB(Bnd)
            m = 2
            h = Ptr
            while READB(h) != ord('\0'):
               m = m + 1
               h = h + 1
            if m > 2:
               WRITEB(Bnd, (src + m))
               if f == 1:
                  #print("#insert")
                  dst = READB(Bnd)
                  while src != Cur:
                     WRITEB(dst, READB(src))
                     dst = dst - 1
                     src = src - 1
                  WRITEB(dst, READB(src))
                  src = Cur
               WRITEB(src, Val)
               #print("#append")
               src = src + 1
               for k in range(m - 1):
                  WRITEB(src, READB(Ptr))
                  Ptr = Ptr + 1
                  src = src + 1



```

以上。