勝手な電子工作・・

勝手なオリジナル電子工作に関する記事を書きます

Arduinoマウスでスピログラフを描く

f:id:a-tomi:20200618150532j:plain

Windows Paintにマウスで書いた?スピログラフ

スピログラフは半世紀も前に流行ったデザイン用のおもちゃで、色んな模様が描けます。その定規は百均でも売られていますが、もはやこれが何であるか知っている人の方が少ないかもしれません。

f:id:a-tomi:20200618151139j:plain

小さな円を大きな円に内接させながら穴に鉛筆やボールペンなどを差し込んでぐるぐる回せば模様が描けます。器用な人だと、この模様をいくつか組み合わせて次のようなデザインをします。

f:id:a-tomi:20200618151355j:plain

 

上の写真は次に載っています。

2020 3D Spirograph Drawing Toys Set Interlocking Gears Wheels Painting Drawing Accessories Creative Educational Toy Children For Creativity From Kidcostume, $2.52 | DHgate.Com

この最初の品は1965年に発売され、以後10年以上も世界で大ヒットしていたらしいです。

Denys Fisher original Spirograph 1965 | ralph stephenson | Flickr

実際使ってみればわかりますが、不器用な人はどこかで失敗して線が違う方向へとずれたりします、私もですが^^; やり直すのもたいへん。

そこで、PCで描けばずっと簡単にできそうです。そのために、まず式を考えます。汚いメモ書きですみませんが。

f:id:a-tomi:20200618152455j:plain

円Bの中心PがΘ回れば、円B自体はがa/b倍だけ逆に回るので、座標軸からみた傾き(Pから穴Qへの向き)としては Θー(a/b)Θ 回ることになります。なので上の式になるわけです。

これさえわかると後は簡単。プログラムで確認すると次のようになります。

youtu.be

画面をカメラで撮ったので少し傾いていてすみません<(_ _)>。

驚くような模様が次々に現れるから不思議です。このプログラム自体は記事の最後の方に載せておきますね。今回はMicrosoft Small Basicでちょこっと作ったシンプルなプログラムです。

さて、これでは当たり前で全然面白くないし、第一に電子工作とは言えませんね。電子工作として子供たちにも見せるには、マウスで描いて見せればよいかなと、忙しいときに余計なことをつい考えついてしまいました。

これならArduinoをマウスとして動かせばすぐにもできそうです。早速作るとしましょう。

前にキーボードを作るために余分に買ったArduino Pro Microが余っていますので、これを使ってみます。このモデルはコンパチ機が流通の主体で、海外だと1つ4ドル前後です。最新のIDEではLeonardoとしてプログラミングします。

考えてみたらこれには特別な回路など殆ど要りませんね。ここでは、単にディジタルピン8にタクトスイッチをつなぐだけにしました。

f:id:a-tomi:20200618154517j:plain

配線はグランドから右へ出した1本だけです。これにタクトスイッチの片側を接続。ハードウェアはたったのこれだけです。

Arduino IDEでプログラミングする際、ボードはLeonardoを指定。プログラム・スケッチは次のとおりで50行ほどの小さなものです。

/* Spirograph drawing machine. Arduino Pro-Micro as a Mouse
   (c)Akira Tominaga  June 15th, 2020                      */
#include "Mouse.h"
#define Button 8      // Button pin
#define bChatT 100     // chattering time
float rA = 300.0;
float rB = 211.0;
float rC = rB * 0.90;
float KakuHi = (rB - rA) / rB;
float Pi = 3.141593;
float gyakuPi = (1.0 / Pi) / 100.0;
int xX;
int yY;
#define pX 0
#define pY 0
#define rBdecr 0.9
#define rCrate 0.8

void setup() {
  pinMode(Button, INPUT_PULLUP);
  Serial.begin(9600);
  Mouse.begin();
  while (digitalRead(Button) == HIGH) {}
  delay(bChatT);
  while (digitalRead(Button) == LOW) {}
}
void loop() {
  int xS = pX;
  int yS = pY;
  int i = 0;
  for (float Theta = 0 ; Theta < 300 * Pi ; Theta = Theta + gyakuPi) {
    if (i > 0) {
      Mouse.press();
    }
    xX = (float)( (rA - rB) * cos(Theta) + rC * cos(KakuHi * Theta));
    yY = (float)( (rA - rB) * sin(Theta) + rC * sin(KakuHi * Theta));
    int Xmove = xX - xS;
    int Ymove = yY - yS;
    Mouse.move(Xmove, Ymove, 0);
    if (digitalRead(Button) == LOW) break;
    xS = xX;
    yS = yY;
    i = 1;
  }
  while (digitalRead(Button) == LOW) {}
  delay(bChatT);
  Mouse.release();
  while (digitalRead(Button) == HIGH) {}
  while (digitalRead(Button) == LOW) {}
  delay(bChatT);
  rB = rB * rBdecr;
  rC = rB * rCrate;
  KakuHi = (rB - rA) / rB;
  delay(300);
}

 操作は次のようにしますが単純です。

お絵描きソフトとして、Windows Paint(マウスで描けるソフトならほかに何でもよいです)を立ち上げ、

①書き始めの地点(出来上がる図形の上下中央の右端になります)にカーソルをもっていく。

②タクトスイッチを押す。するとスピログラフを描き出します。

止めたいところで再び

③タクトスイッチを押せばとまります。

youtu.be

止まっている間にブラシや鉛筆、色などを選んでからカーソルの場所を移動して①②③を繰り返せば色や太さが選べます。

 

これなら子供達の前で見せたり、どや顔もできそう。色々工夫すれば好きなことができますが、何も役立ちませんね^^

最後にWindowsの一番簡単な言語と思われるSmall Basicで書いたプログラムを入れておきます。outputは最初のほうに出した動画です。もちろん言語は何でもよいです。

myTitle="Automatic Spirograph V00  (c)2020 A.Tominaga "

' GraphicsWindow definition
Gt=10 ' top edge position
Gl=50 ' left edge position
Gw=900 ' window width
Gh=900 ' window height
Ds=1.25 'display scaling rate is 125% in this case
GraphicsWindow.top=Gt
GraphicsWindow.Left=Gl
GraphicsWindow.Width=Gw
GraphicsWindow.Height=Gh
GraphicsWindow.Title=myTitle

' TextWindow definition
Tt=(Gt+Gh)*Ds-377 'adjusted text window's top edge position
Tl=(Gl+Gw)*Ds+2   ' set clearance with graphic window
TextWindow.top=Tt
TextWindow.left=Tl
TextWindow.Title=myTitle

' Radii of Circles
rA=400 'A circle radius
rBdefault=171
Inq:
TextWindow.Write("*** rA=400. Input rB initial size -> ")
rBinit=TextWindow.Read() 'B circle radius specified
If rBinit="" Then
  rBinit=rBdefault
EndIf
If rB>rA-1 Then
  goto Inq
EndIf 
rCdefault=0.7 ' default C radius ratio to rB

' Main processes
For rB= rBinit To 350
  rC=Math.Round(rB*rCdefault)
  ' define pen colors
  cR=Math.GetRandomNumber(255)
  getcG:
  cG=Math.GetRandomNumber(255)
  If cR+cG>320 Then
    Goto getcG
  EndIf
  cB=Math.Round(255-(cR+cG)/1.2)
  GraphicsWindow.PenColor=GraphicsWindow.GetColorFromRGB(cR,cG,cB)
  GraphicsWindow.PenWidth=1
  
  'draw Spirograph
  GraphicsWindow.Clear()
  XS=Gw/2 ' initial X position
  YS=Gh/2 ' initial Y position
  ' Loop to draw graph
  for theta= 0 To 500 Step 0.2
    XX=(rA-rB)*Math.Cos(theta)+rC*Math.Cos(theta*(rB-rA)/rB)+Gw/2
    YY=(rA-rB)*Math.Sin(theta)+rC*Math.Sin(theta*(rB-rA)/rB)+Gh/2
    If theta>0 then ' exclude initial position
      GraphicsWindow.DrawLine(XS,YS,XX,YY)
    EndIf
    XS=XX
    YS=YY
  EndFor

  ' Draw legend to show radius values of  A, B, and C
  fontSize=20
  GraphicsWindow.FontSize=fontSize 
  fontW=fontSize/2 ' font width average to be
  Lx=150 ' legend characters' X-position
  Ly=65  ' legend characters' Y-position
  Legend="Radii   A=400   B="
  LegLen=Text.GetLength(Legend)
  GraphicsWindow.DrawText(Lx,Ly,Legend)
  GraphicsWindow.DrawText(Lx+LegLen*fontW+2,Ly,rB)
  LegLen2p=Lx+(LegLen+4)*fontW 'Len2 as pixel number
  GraphicsWindow.DrawText(LegLen2p,Ly,"  C=")
  GraphicsWindow.DrawText(LegLen2p+4*fontW+2,Ly,rC)
  Name="Programmmed by A. Tominaga"
  NameLen=Text.GetLength(Name)
  fontSize=fontSize*0.6
  GraphicsWindow.FontSize=fontSize
  fontW=fontSize/2
  Lx=Gw-(NameLen*fontW+Lx)
  GraphicsWindow.DrawText(Lx,Ly+fontW,Name)
  Program.Delay(1000)
EndFor

Sound.PlayBellRing()
Program.Delay(2000)
Program.End()

今回は単純で「どこが工作?」という感じではありますが、このへんで失礼したいと思います。

後で気づいたので補足します:三角関数は中学校で習うものと思っていたら、今は高校のようです。このIT時代に不思議なことですね。

 

©2020 Akira Tominaga, All rights reserved.