nakkaya / clodiuno Goto Github PK
View Code? Open in Web Editor NEWClojure API for the firmata protocol.
Home Page: http://nakkaya.com/clodiuno.html
License: Other
Clojure API for the firmata protocol.
Home Page: http://nakkaya.com/clodiuno.html
License: Other
I wanted to add custom SYSEX command to my arduino and to debug this I wanted to get debug messages from it. However, I can't see any information that is being sent from the arduino.
Here is the code of the sketch:
#include <Firmata.h>
void sysexCallback(byte command, byte argc, byte *argv)
{
Firmata.sendString("Recieved sysex command\n");
}
void setup()
{
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
Firmata.attach(START_SYSEX, sysexCallback);
Firmata.begin(57600);
}
void loop()
{
while(Firmata.available())
Firmata.processInput();
Firmata.sendString("Test message");
delay(1000);
}
Here is the code that I use to bootstrap cloduino:
(ns arbasic.core
(:require [clodiuno.core :refer :all])
(:require [clodiuno.firmata :refer :all])
(:gen-class))
(defn log [msg] (println msg))
(defn get-board [] (arduino :firmata "/dev/tty.usbmodem1411" :msg-callback log))
What I expect is that when I run (def board (get-board))
in emacs repl I should start getting messages from the arduino and they should be printed in the repl, but it doesn't happen.
I've tried to insert debug statements in different parts of the library and it seems, that println outputs into repl in all code that is called directly from me, but no output appears from the code that acts as callback form serial port events.
E.g., I've modified the process-input function this way:
(defn- process-input
"Parse input from firmata."
[conn in]
(while (> (.available in) 2)
(let [data (.read in)]
(println "data in")
(cond
(= (bit-and data 0xF0) ANALOG-MESSAGE) (let [pin (bit-and data 0x0F)
[_ _ val] (read-multibyte in)]
(assoc-in! conn [:analog pin] val))
(= (bit-and data 0xF0) DIGITAL-MESSAGE) (let [port (bit-and data 0x0F)
[lsb msb val] (read-multibyte in)]
(assoc-in! conn [:digital-in port] (bits val)))
(= data REPORT-VERSION) (assoc-in! conn [:version] [(.read in) (.read in)])
(= data START-SYSEX) (handle-sysex conn in)))))
Although I know that this code is executed at least once to get the version, I see no "data in" messages in the repl.
What can be wrong in the code? I'm new to clojure so I assume that I'm doing something wrong and the library code behaves the right way, but I don't see any obvious mistakes in the code.
Hi, clodiuno is nice, thanks for that! :D
I'm stuck with exception. Here my code:
(ns clojure-arduino.core
(:use :reload-all clodiuno.core)
(:use :reload-all clodiuno.firmata))
(System/setProperty "gnu.io.rxtx.SerialPorts" "/dev/ttyACM0")
(defn -main []
(let [board (arduino :firmata "/dev/ttyACM0")]
(Thread/sleep 5000)
(pin-mode board 12 OUTPUT)
(digital-write board 12 HIGH)
(close board)))
Here is my exception message:
Exception in thread "main" java.lang.NullPointerException (NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:5440)
at clojure.lang.Compiler.eval(Compiler.java:5415)
at clojure.lang.Compiler.eval(Compiler.java:5391)
at clojure.core$eval.invoke(core.clj:2382)
at clojure.main$eval_opt.invoke(main.clj:235)
at clojure.main$initialize.invoke(main.clj:254)
at clojure.main$null_opt.invoke(main.clj:279)
at clojure.main$main.doInvoke(main.clj:354)
at clojure.lang.RestFn.invoke(RestFn.java:422)
at clojure.lang.Var.invoke(Var.java:369)
at clojure.lang.AFn.applyToHelper(AFn.java:165)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at clodiuno.firmata$fn__129.invoke(firmata.clj:95)
at clojure.lang.MultiFn.invoke(MultiFn.java:171)
at clojure_arduino.core$_main.invoke(core.clj:12)
at clojure.lang.Var.invoke(Var.java:361)
at user$eval38.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:5424)
... 12 more
As I can see firmata.clj:95
tries to access :digital-out
from conn map that is nil.
Thanks for help
Max
Hi Nakkaya,
Thanks for clodiuno!
I'm beginning my journey with arduino (uno) and i try to use clodiuno for that.
Here's my project.clj :
(defproject arduino-lab "1.0.0-SNAPSHOT"
:description "Mess around with arduino from the comfort of the repl"
:dependencies [[org.clojure/clojure "1.3.0"]
[clodiuno "0.0.3-SNAPSHOT"]
[serial-port "1.1.2"]]
:native-dependencies [[org.clojars.samaaron/rxtx "2.2.0.1"]]
:dev-dependencies [[native-deps "1.0.5"]]
:jvm-opts ["-Djava.library.path=./native/linux/x86/"
"-d32"])
Ii already got over the jar problems... i'm on ubuntu GNU/Linux and on the naming convention, RXTXcomm.jar look only for devices with /dev/ttySxx and on my machine it's /dev/ttyACM0.
But, i got stuck at the very beginning just after that:
arduino-lab.sos> (def bd (arduino :firmata "/dev/ttyS42"))
arduino-lab.sos> bd
#<Ref@11cac41: {:digital-in {2 (0 0 0 0 0 0 0 0), 1 (0 0 0 0 0 0 0 0), 0 (0 0 0 0 0 0 0 0)}, :version [2 2], :port #<RXTXPort /dev/ttyS42>, :interface :firmata}>
As you can see, the :digital-out key is not populated.
This causes a NullPointerException on the call of digital-write
call here - https://github.com/nakkaya/clodiuno/blob/master/src/clodiuno/firmata.clj#L95
When i look at the code that's in charge of populated it - on the arduino
multi-method in the firmata
namespace - https://github.com/nakkaya/clodiuno/blob/master/src/clodiuno/firmata.clj#L147.
(dotimes [i (count (keys (:digital-in @conn)))]
(assoc-in! conn [:digital-out i] (repeat 8 0))))
If i wrap this into a function (change directly into the jar and restarting the clojure-jack-in process), the digital-out
is then populated:
arduino-lab.sos> (def bd (arduino :firmata "/dev/ttyS42"))
arduino-lab.sos> bd
#<Ref@152c19d: {:digital-out {2 (0 0 0 0 0 0 0 0), 1 (0 0 0 0 0 0 0 0), 0 (0 0 0 0 0 0 0 0)}, :digital-in {2 (0 0 0 0 0 0 0 0), 1 (0 0 0 0 0 0 0 0), 0 (0 0 0 0 0 0 0 0)}, :version [2 2], :port #<RXTXPort /dev/ttyS42>, :interface :firmata}>
And now i can play :D and it is working fine.
Do you have any idea as of why such a behaviour ?
Anyway, can i make you a pull request for this (the wrapping into a private function) ?
1. Caused by java.lang.NoClassDefFoundError
Could not initialize class gnu.io.RXTXPort
Hi Nurullah,
Clodiuno is super cool, thanks for doing it!
I'm a proud and excited owner of an Arduino Mega 2560, from udrones:
http://www.udrones.com/product_p/expck1.htm
I got it hooked up to my Mac, and followed your instructions for getting Cloduino going. Your basic example of making the LED on pin 13 blink, works fine. Thanks!
Now I'm wondering how to read data from the GPS which I've plugged in? I'm a total newb here, so I don't even know which pins to read, or whether I need to read analog or digital?
But I've tried every combination of things I can think of.
I've done this, thinking it's the way to prepare all pins for reading:
(dorun (map #(pin-mode board % INPUT) (range 72)))
And then I've tried...
(digital-read board i)
... for all legal pin numbers in place of i. I get 0 back for every call.
So then I've tried...
(analog-read board i)
... for all legal pin numbers in place of i. I get the same NPE for every call:
No message.
[Thrown class java.lang.NullPointerException]
Restarts:
0: [QUIT] Quit to the SLIME top level
Backtrace:
0: firmata.clj:110 clodiuno.firmata/eval1980[fn]
1: MultiFn.java:167 clojure.lang.MultiFn.invoke
2: NO_SOURCE_FILE:1 arduclj.core/eval2136
3: Compiler.java:6465 clojure.lang.Compiler.eval
4: Compiler.java:6431 clojure.lang.Compiler.eval
5: core.clj:2795 clojure.core/eval
6: basic.clj:47 swank.commands.basic/eval-region
7: basic.clj:37 swank.commands.basic/eval-region
8: basic.clj:71 swank.commands.basic/eval956[fn]
9: Var.java:401 clojure.lang.Var.invoke
--more--
I really am a newb here! May I ask you how I can go about getting input from the pins? And how to find out which pins to read for the GPS? (Or any sensor, for that matter?)
Thanks again for such a cool and fun project to play with, and any help or tips are greatly appreciated...
Aaron
Hi!
Thank you for your library and for your projects, because they are almost the single source of information regarding arduino and clojure.
I'm trying to add custom SYSEX commands in order to control the motorshield on the arduino and only pass high level commands to it (I'm using AF_motor library and I'm not sure if it's possible to reimplement it's functionality with simple analogWrite etc.)
I tried to receive the debug information from the arduino passing :msg-callback parameter with no luck. What I noticed is that the support of :msg-callback was added long after the last version was released, so probably the version of library I got with the lein deps simply does not contain this functionality.
Could you please upgrage the version of library, so that everyone can benefit from latest features?
My board(Duemilanove with Atmega328) is mounted at /dev/ttyUSB0 and I'm getting a NoSuchPortException
when I try
(arduino :firmata "/dev/USB0")
I'm not sure why this is happening. On the IDE, Serial Port is set to /dev/USB0 too and serial monitoring works fine in the IDE.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.