hArduino 0.7 → 0.8
raw patch · 8 files changed
+164/−5 lines, 8 files
Files
- CHANGES.md +7/−1
- System/Hardware/Arduino.hs +2/−2
- System/Hardware/Arduino/Data.hs +1/−1
- System/Hardware/Arduino/Firmata.hs +14/−0
- System/Hardware/Arduino/Parts.hs +3/−0
- System/Hardware/Arduino/Parts/Piezo.hs +91/−0
- System/Hardware/Arduino/SamplePrograms/JingleBells.hs +43/−0
- hArduino.cabal +3/−1
CHANGES.md view
@@ -1,7 +1,13 @@ * Hackage: (http://hackage.haskell.org/package/hArduino) * GitHub: (http://leventerkok.github.com/hArduino) -* Latest Hackage released version: 0.7+* Latest Hackage released version: 0.8++### Version 0.8, 2013-12-15+ * Add support for Piezo speakers+ * Add simple musical note playing support, and a+ jingle-bells playing example. (Not a great+ rendering, but still recognizable!) ### Version 0.7, 2013-11-09 * Export LCD type, for ease of programming
System/Hardware/Arduino.hs view
@@ -17,8 +17,8 @@ -- * Programming the Arduino -- ** Pins , analog, digital, pin, Pin, PinMode(..), setPinMode- -- ** Analog input- , analogRead+ -- ** Analog input/output (PWM)+ , analogRead, analogWrite -- ** Digital I/O , digitalWrite, digitalRead -- ** Programming with triggers
System/Hardware/Arduino/Data.hs view
@@ -9,7 +9,6 @@ -- Underlying data structures ------------------------------------------------------------------------------- -{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RankNTypes #-}@@ -458,6 +457,7 @@ , digitalReportingPins = dPins } return (bst', acts1 ++ acts2)+getModeActions _ PWM = return [] getModeActions _ OUTPUT = return [] getModeActions _ SERVO = return [] getModeActions p m = die ("hArduino: getModeActions: TBD: Unsupported mode: " ++ show m) ["On pin " ++ show p]
System/Hardware/Arduino/Firmata.hs view
@@ -264,6 +264,20 @@ Just (Right v) -> v _ -> 0 -- no (correctly-typed) value reported yet, default to 0 +-- | Write a PWM analog value to a pin. The argument is an 'Int', indicating the duty cycle.+-- @0@ means off; @255@ means always on. Intermediate values will create a square wave+-- on that pin with the given duty-cycle+analogWrite :: Pin -> Int -> Arduino ()+analogWrite p' dc = do+ (p, _) <- convertAndCheckPin "analogWrite" p' PWM+ when (dc < 0 || dc > 255) $ die ("Invalid duty-cycle value for PWM write on pin " ++ show p)+ [ "Values should be between 0 and 255"+ , "Received: " ++ show dc+ ]+ send $ AnalogPinWrite p (fromIntegral lsb) (fromIntegral msb)+ where lsb = dc .&. 0x7f+ msb = (dc `shiftR` 7) .&. 0x7f+ -- | Set the analog sampling interval, in milliseconds. Arduino uses a default of 19ms to sample analog and I2C -- signals, which is fine for many applications, but can be modified if needed. The argument -- should be a number between @10@ and @16384@; @10@ being the minumum sampling interval supported by Arduino
System/Hardware/Arduino/Parts.hs view
@@ -17,11 +17,14 @@ , module System.Hardware.Arduino.Parts.ShiftRegisters -- * Servo-motors , module System.Hardware.Arduino.Parts.Servo+ -- * Piezo-speakers+ , module System.Hardware.Arduino.Parts.Piezo ) where import System.Hardware.Arduino.Parts.LCD import System.Hardware.Arduino.Parts.SevenSegmentCodes import System.Hardware.Arduino.Parts.ShiftRegisters import System.Hardware.Arduino.Parts.Servo+import System.Hardware.Arduino.Parts.Piezo {-# ANN module "HLint: ignore Use import/export shortcut" #-}
+ System/Hardware/Arduino/Parts/Piezo.hs view
@@ -0,0 +1,91 @@+-------------------------------------------------------------------------------------------------+-- |+-- Module : System.Hardware.Arduino.Parts.Piezo+-- Copyright : (c) Levent Erkok+-- License : BSD3+-- Maintainer : erkokl@gmail.com+-- Stability : experimental+--+-- Abstractions for piezo speakers. +-------------------------------------------------------------------------------------------------++{-# LANGUAGE NamedFieldPuns #-}+module System.Hardware.Arduino.Parts.Piezo(+ -- * Declaring a piezo speaker+ Piezo, speaker+ -- * Notes you can play, and durations+ , Note(..), Duration(..)+ -- * Playing a note, rest, or silencing+ , playNote, rest, silence+ -- * Play a sequence of notes:+ , playNotes+ ) where++import Data.Bits (shiftR, (.&.))+import Data.Maybe (fromMaybe)++import System.Hardware.Arduino+import System.Hardware.Arduino.Comm+import System.Hardware.Arduino.Data++-- | A piezo speaker. Note that this type is abstract, use 'speaker' to+-- create an instance.+data Piezo = Piezo { piezoPin :: IPin -- ^ The internal-pin that controls the speaker+ , tempo :: Int -- ^ Tempo for the melody+ }++-- | Create a piezo speaker instance.+speaker :: Int -- ^ Tempo. Higher numbers mean faster melodies; in general.+ -> Pin -- ^ Pin controlling the piezo. Should be a pin that supports PWM mode.+ -> Arduino Piezo+speaker t p = do debug $ "Attaching speaker on pin: " ++ show p+ setPinMode p PWM+ (ip, _) <- convertAndCheckPin "Piezo.speaker" p PWM+ return Piezo { piezoPin = ip, tempo = t }++-- | Musical notes, notes around middle-C+data Note = A | B | C | D | E | F | G | R deriving (Eq, Show) -- R is for rest++-- | Beat counts+data Duration = Whole | Half | Quarter | Eight deriving (Eq, Show)++-- | Convert a note to its frequency appropriate for Piezo+frequency :: Note -> Int+frequency n = fromMaybe 0 (n `lookup` fs)+ where fs = [(A, 440), (B, 493), (C, 261), (D, 294), (E, 329), (F, 349), (G, 392), (R, 0)]++-- | Convert a duration to a delay amount+interval :: Piezo -> Duration -> Int+interval p Whole = 8 * interval p Eight+interval p Half = 4 * interval p Eight+interval p Quarter = 2 * interval p Eight+interval p Eight = tempo p++-- | Turn the speaker off+silence :: Piezo -> Arduino ()+silence (Piezo p _) = send $ AnalogPinWrite p 0 0++-- | Keep playing a given note on the piezo:+setNote :: Piezo -> Note -> Arduino ()+setNote (Piezo p _) n = send $ AnalogPinWrite p (fromIntegral lsb) (fromIntegral msb)+ where f = frequency n+ lsb = f .&. 0x7f+ msb = (f `shiftR` 7) .&. 0x7f++-- | Play the given note for the duration+playNote :: Piezo -> (Note, Duration) -> Arduino ()+playNote pz (n, d) = do setNote pz n+ delay (interval pz d)+ silence pz++-- | Play a sequence of notes with given durations:+playNotes :: Piezo -> [(Note, Duration)] -> Arduino ()+playNotes pz = go+ where go [] = silence pz+ go (nd@(_, d):r) = do playNote pz nd+ delay (interval pz d `div` 3) -- heuristically found.. :-)+ go r++-- | Rest for a given duration:+rest :: Piezo -> Duration -> Arduino ()+rest pz d = delay (interval pz d)
+ System/Hardware/Arduino/SamplePrograms/JingleBells.hs view
@@ -0,0 +1,43 @@+-------------------------------------------------------------------------------+-- |+-- Module : System.Hardware.Arduino.SamplePrograms.JingleBells+-- Copyright : (c) Levent Erkok+-- License : BSD3+-- Maintainer : erkokl@gmail.com+-- Stability : experimental+--+-- A (pretty bad!) rendering of Jingle Bells on a piezo speaker+-------------------------------------------------------------------------------++module System.Hardware.Arduino.SamplePrograms.JingleBells where++import System.Hardware.Arduino+import System.Hardware.Arduino.Parts.Piezo++-- | Notes for jingle-bells. Expecting a nice rendering from this encoding+-- on a piezo speaker would be naive.. However, it's still recognizable!+jingleBells :: [(Note, Duration)]+jingleBells = m1 ++ m1 ++ m3 ++ m4 ++ wait ++ m5 ++ m6 ++ m7 ++ m8 ++ wait+ ++ m1 ++ m1 ++ m3 ++ m4 ++ wait ++ m5 ++ m6 ++ m15 ++ m16+ where m1 = [(E, Quarter), (E, Quarter), (E, Half)]+ m3 = [(E, Quarter), (G, Quarter), (C, Quarter), (D, Quarter)]+ m4 = [(E, Whole)]+ m5 = replicate 4 (F, Quarter)+ m6 = (F, Quarter) : replicate 3 (E, Quarter)+ m7 = [(E, Quarter), (D, Quarter), (D, Quarter), (E, Quarter)]+ m8 = [(D, Half), (G, Half)]+ m15 = [(G, Quarter), (G, Quarter), (F, Quarter), (D, Quarter)]+ m16 = [(C, Whole)]+ wait = [(R, Half)]++-- | Play the jingle-bells on a PWM line, attached to pin 3. We use a +-- tempo of @75@; which is fairly fast. For a slower rendring try @150@+-- or higher values.+--+-- The circuit simple has a piezo speaker attached to pin 3.+--+-- <<http://github.com/LeventErkok/hArduino/raw/master/System/Hardware/Arduino/SamplePrograms/Schematics/Piezo.png>>+main :: IO ()+main = withArduino False "/dev/cu.usbmodemfd131" $ do+ pz <- speaker 75 (pin 3)+ playNotes pz jingleBells
hArduino.cabal view
@@ -1,5 +1,5 @@ Name: hArduino-Version: 0.7+Version: 0.8 Category: Hardware Synopsis: Control your Arduino board from Haskell. Description: hArduino allows Haskell programs to control Arduino boards (<http://www.arduino.cc>)@@ -32,11 +32,13 @@ , System.Hardware.Arduino.Parts.ShiftRegisters , System.Hardware.Arduino.Parts.SevenSegmentCodes , System.Hardware.Arduino.Parts.Servo+ , System.Hardware.Arduino.Parts.Piezo , System.Hardware.Arduino.SamplePrograms.Analog , System.Hardware.Arduino.SamplePrograms.Blink , System.Hardware.Arduino.SamplePrograms.Button , System.Hardware.Arduino.SamplePrograms.Counter , System.Hardware.Arduino.SamplePrograms.Distance+ , System.Hardware.Arduino.SamplePrograms.JingleBells , System.Hardware.Arduino.SamplePrograms.LCD , System.Hardware.Arduino.SamplePrograms.NumGuess , System.Hardware.Arduino.SamplePrograms.Pulse