Motor Control via Ardumoto Using Arduino and Clodiuno

Here is another post that is partly for documentation and partly for safekeeping. Following snippet which I ripped from another robot we have been working on, demonstrates how to control the Ardumoto motor driver shield using Clodiuno.

Control for motor attached to OUT 1-2 is connected to digital line 12 (direction) and digital line 10 (PWM). Control for motor attached to OUT 3-4 is connected to digital line 13 (direction) and digital line 11 (PWM).

 (ns ardumoto.core
   (:use [clojure.contrib.swing-utils :only [add-action-listener]])
   (:use clodiuno.core)
   (:use clodiuno.firmata)
   (:import (javax.swing JFrame JPanel JButton)
            (net.miginfocom.swing MigLayout)))

 (def pwm-pin-motor-a 10)
 (def pwm-pin-motor-b 11)
 (def dir-pin-motor-a 12)
 (def dir-pin-motor-b 13)

 (def speed 200)

 (defn board []
   (arduino :firmata "/dev/tty.usbserial-A6008nhh"))

 (defn init-pins [board]
   (pin-mode board pwm-pin-motor-a PWM)
   (pin-mode board pwm-pin-motor-b PWM)
   (pin-mode board dir-pin-motor-a OUTPUT)
   (pin-mode board dir-pin-motor-b OUTPUT))

 (defn motor [board m p]
   (let [motor-pin (if (= m :a) pwm-pin-motor-a pwm-pin-motor-b)
         dir-pin   (if (= m :a) dir-pin-motor-a dir-pin-motor-b)
         pwm   (if (< p 0) (* -1 p) p)
         dir   (if (< p 0) LOW HIGH)]
     (analog-write board motor-pin pwm)
     (digital-write board dir-pin dir)))

 (defn listener [press-f release-f]
   (proxy [java.awt.event.MouseListener] [] 
     (mousePressed [e] (press-f))
     (mouseReleased [e] (release-f))
     (mouseClicked [e])
     (mouseEntered [e])
     (mouseExited [e])))

 (defn panel []
   (let [arduino (ref nil)
         panel (JPanel. (MigLayout.))
         left (JButton. "Left")
         right (JButton. "Right")
         forward (JButton. "Forward")
         backward (JButton. "Backward")
         connect  (JButton. "Connect")
         init  (JButton. "Init")
         set-speed #(do (motor @arduino :a %1) (motor @arduino :b %2))
         stop #(do (motor @arduino :a 0) (motor @arduino :b 0))]

     (add-action-listener connect (fn[_] (dosync (ref-set arduino (board)))))
     (add-action-listener init (fn[_] (init-pins @arduino)))

     (.addMouseListener left (listener #(set-speed (* -1 speed) speed) stop))
     (.addMouseListener right (listener #(set-speed speed (* -1 speed)) stop))
     (.addMouseListener forward (listener #(set-speed speed speed) stop))
     (.addMouseListener 
      backward (listener #(set-speed (* -1 speed) (* -1 speed)) stop))

     (doto panel
       (.add forward "cell 3 1")
       (.add backward "cell 3 3")
       (.add left "cell 2 2")
       (.add right "cell 4 2")
       (.add connect "cell 2 4")
       (.add init "cell 4 4"))))

 (defn frame []
   (let [panel (panel)]
     (doto (JFrame.)
       (.add panel)
       (.pack)
       (.setVisible true))))