From 7c894e7e67d73fcabb253c96b56dc6d095f181fa Mon Sep 17 00:00:00 2001 From: Nurullah Akkaya Date: Wed, 4 Aug 2010 15:30:51 +0300 Subject: [PATCH] implement Digital/Analog I/O. --- resources/SocketApp/SocketApp.pde | 10 ++-- resources/SocketApp/handler.h | 76 ++++++++++++++++++++++++++----- src/clodiuno/core.clj | 18 ++++---- src/clodiuno/wishield.clj | 43 +++++++++++++---- 4 files changed, 112 insertions(+), 35 deletions(-) diff --git a/resources/SocketApp/SocketApp.pde b/resources/SocketApp/SocketApp.pde index 8b1e481..e81a57a 100644 --- a/resources/SocketApp/SocketApp.pde +++ b/resources/SocketApp/SocketApp.pde @@ -49,12 +49,10 @@ unsigned char ssid_len; unsigned char security_passphrase_len; //--------------------------------------------------------------------------- -void setup() -{ - WiFi.init(); +void setup(){ + WiFi.init(); } -void loop() -{ - WiFi.run(); +void loop(){ + WiFi.run(); } diff --git a/resources/SocketApp/handler.h b/resources/SocketApp/handler.h index a77e418..7e21ce2 100644 --- a/resources/SocketApp/handler.h +++ b/resources/SocketApp/handler.h @@ -1,40 +1,92 @@ -#include "WProgram.h" -#include +#include +int parsePin(char* msg){ + char pin[] = {msg[2],msg[3]}; + return atoi(pin); +} + +int cmdCmpr(char* msg, char* expected){ + if (msg[0] == expected[0] && msg[1] == expected[1]) + return true; + else + return false; +} char* setPinMode(char* msg){ - char pin[] = {msg[2],msg[3]}; + int pin = parsePin(msg); char mode = msg[4]; if (mode == 'o'){ - pinMode(atoi(pin), OUTPUT); + digitalWrite(pin, LOW); // disable PWM + pinMode(pin, OUTPUT); return "OK\n"; }else if (mode == 'i'){ - pinMode(atoi(pin), INPUT); + pinMode(pin, INPUT); + return "OK\n"; + }else if (mode == 'a'){ + digitalWrite(pin + 14, LOW); // disable internal pull-ups + pinMode(pin + 14, INPUT); + return "OK\n"; + }else if (mode == 'p'){ + pinMode(pin, OUTPUT); return "OK\n"; }else - return "Error.\n"; + return "Error\n"; } char* setDigitalWrite(char* msg){ - char pin[] = {msg[2],msg[3]}; + int pin = parsePin(msg); char mode = msg[4]; if (mode == 'h'){ - digitalWrite(atoi(pin), HIGH); + digitalWrite(pin, HIGH); return "OK\n"; }else if (mode == 'l'){ - digitalWrite(atoi(pin), LOW); + digitalWrite(pin, LOW); return "OK\n"; }else - return "Error.\n"; + return "Error\n"; +} + +char* setAnalogWrite(char* msg){ + int pin = parsePin(msg); + char val[] = {msg[4], msg[5], msg[6]}; + + analogWrite(pin, atoi(val)); + return "OK\n"; +} + +char* getDigitalRead(char* msg){ + int pin = parsePin(msg); + + char buff [20]; + itoa(digitalRead(pin),buff,10); + + strncat(buff,"\n",1); + return buff; +} + +int getAnalogRead(char* msg){ + int pin = parsePin(msg); + + char buff [20]; + itoa(analogRead(pin),buff,10); + + strncat(buff,"\n",1); + return buff; } char* process(char* msg){ - if (msg[0] == 'p' && msg[1] == 'm') + if (cmdCmpr(msg,"pm")) return setPinMode(msg); - else if (msg[0] == 'd' && msg[1] == 'w') + else if (cmdCmpr(msg,"dw")) return setDigitalWrite(msg); + else if (cmdCmpr(msg,"aw")) + return setAnalogWrite(msg); + else if (cmdCmpr(msg,"dr")) + return getDigitalRead(msg); + else if (cmdCmpr(msg,"ar")) + return getAnalogRead(msg); else return "Unknown Command.\n"; } diff --git a/src/clodiuno/core.clj b/src/clodiuno/core.clj index efa3b55..b3fd1b2 100644 --- a/src/clodiuno/core.clj +++ b/src/clodiuno/core.clj @@ -16,17 +16,17 @@ "Write a HIGH or a LOW value to a digital pin." (fn [type _ _] (type :interface))) -;; (defmulti digital-read -;; "Read a HIGH or a LOW value from a digital pin." -;; (fn [type] ((meta type) :interface))) +(defmulti digital-read + "Read a HIGH or a LOW value from a digital pin." + (fn [type _] (type :interface))) -;; (defmulti analog-read -;; "Reads the value from the specified analog pin." -;; (fn [type] ((meta type) :interface))) +(defmulti analog-read + "Reads the value from the specified analog pin." + (fn [type _] (type :interface))) -;; (defmulti analog-write -;; "Write an analog value (PWM-wave) to a digital pin." -;; (fn [type] ((meta type) :interface))) +(defmulti analog-write + "Write an analog value (PWM-wave) to a digital pin." + (fn [type _ _] (type :interface))) (defmulti close "Close serial interface." diff --git a/src/clodiuno/wishield.clj b/src/clodiuno/wishield.clj index f94f1b3..f7b45f8 100644 --- a/src/clodiuno/wishield.clj +++ b/src/clodiuno/wishield.clj @@ -2,10 +2,12 @@ #^{:author "Nurullah Akkaya", :doc "WiShield Library for Clojure."} (:use clodiuno.core :reload-all) - (:import (java.net Socket) + (:import (java.text DecimalFormat) + (java.net Socket) (java.io PrintWriter InputStreamReader BufferedReader))) -(derive ::wishield ::interface) +(def pin-format (DecimalFormat. "00")) +(def pwm-format (DecimalFormat. "000")) (def INPUT 0) ;;pin to input mode (def OUTPUT 1) ;;pin to output mode @@ -26,22 +28,34 @@ (defmethod disable-pin :wishield [board type pin]) (defmethod pin-mode :wishield [board pin mode] - (let [pin (if (< pin 10) (str "0" pin) (str pin)) + (let [pin (.format pin-format pin) mode (cond (= mode INPUT) "i" (= mode OUTPUT) "o" (= mode ANALOG) "a" (= mode PWM) "p" - (= mode SERVO) "s" + ;;(= mode SERVO) "s" :default (throw (Exception. "Invalid Mode.")))] (send-command board (str "pm" pin mode)))) (defmethod digital-write :wishield [board pin value] - (let [pin (if (< pin 10) (str "0" pin) (str pin)) + (let [pin (.format pin-format pin) value (cond (= value HIGH) "h" (= value LOW) "l" :default (throw (Exception. "Invalid Value.")))] (send-command board (str "dw" pin value)))) +(defmethod analog-write :wishield [board pin value] + (send-command + board (str "aw" (.format pin-format pin) (.format pwm-format value)))) + +(defmethod analog-read :wishield [board pin] + (read-string + (send-command board (str "ar" (.format pin-format pin))))) + +(defmethod digital-read :wishield [board pin] + (read-string + (send-command board (str "dr" (.format pin-format pin))))) + (defmethod close :wishield [board] (let [{:keys [in out socket]} board] (send-command board "bye") @@ -60,9 +74,22 @@ (comment (def board (arduino "10.0.2.100" 1000)) - (pin-mode board 6 OUTPUT) - (digital-write board 6 HIGH) - (digital-write board 6 LOW) + (do + (pin-mode board 3 OUTPUT) + (pin-mode board 6 INPUT) + (while true + (let [i (digital-read board 6)] + (println i) + (digital-write board 3 i)))) + + (let [map (fn [x in-min in-max out-min out-max] + (+ (/ (* (- x in-min) (- out-max out-min)) + (- in-max in-min)) out-min))] + (pin-mode board 3 PWM) + (pin-mode board 5 ANALOG) + + (while true (analog-write board 3 + (map (analog-read board 5) 0 1023 0 255)))) (close board) )