2
$\begingroup$

I'm attempting to read data sent by an Arduino program over the serial port. To make it simple, I've uploaded a program to the Arduino so that it just sends the value of an integer every fifth of a second, and then increments it. I know it works because I can see the output in a serial monitor and it's not really the issue at hand, but here's the code anyway:

#include <SPI.h>

int counter = 1;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {
  Serial.println(counter);
  counter++;
  delay(200);
}

The real problem is reading it in with Mathematica. I'm positive the port is COM8, because that's the one selected in the Arduino IDE, and if I try to open the port in Mathematica while the serial monitor in the Arduino IDE is open, it won't open.

Here's my Mathematica code:

ReadSerialPort[] := Module[{serial, dat},
  serial = DeviceOpen["Serial", {"COM8", "BaudRate" -> 9600}];
  (*dat=DeviceReadBuffer[serial,10];*)
  dat = DeviceRead[serial];
  DeviceClose[serial];
  Print@dat;
  ]

As you can see, I tried both DeviceRead and DeviceReadBuffer (separately), with the same result: $TimedOut.

I found this Wolfram community post from about two years ago, where apparently there was a bug and the solution is to add "\.\" in from of the COM... but I tried that and it gave me a "doesn't recognize escape character C" error.

What else can I try?

edit: I've also tried doing Serial.write() in the Arduino program, and doing the serial at 115200 baud, but neither fixed the problem.

$\endgroup$
  • $\begingroup$ Have you read about the the built-in support for Arduino in the documentation? Does that work? (It might give further clues; I've successfully used an Arduino in the way you try to do it here, but I don't see any problems. Double check that "COM8" is right, perhaps.) $\endgroup$ – C. E. Oct 22 '16 at 23:15
  • $\begingroup$ Please, add info about your mathematica version. Most first timers to leave the ARDUINO Sketch open during the Mathematica data capture session.Close the Arduino sketch after download. $\endgroup$ – Jose Enrique Calderon Oct 24 '16 at 12:00
  • $\begingroup$ @JoseECalderon ahh, I didn't realize I have to close the Sketch (IDE, right?) as well; I thought it was just the serial monitor that would be blocking it. I'll try this when I get home. $\endgroup$ – YungHummmma Oct 24 '16 at 20:15
2
$\begingroup$

Your code works for me, so I cannot say why it's not working for you.

However, there's built-in support for Arduino in Mathematica. You can control the entire thing from the Notebook, for your problem I'd do something like:

(*Connect to the Arduino.*)
arduino = DeviceOpen["Arduino", "COM6"]
(* Define the initialization code. *)
prependedCode = "int counter = 0;";
(* Functions for the counter. *)
incrementCounter = <|
   "ArgumentTypes" -> {},
   "ReturnType" -> {},
   "Code" -> "
        void incrementCounter() {
            counter++;
        }"|>;
getCount = <|
   "ArgumentTypes" -> {},
   "ReturnType" -> Integer,
   "Code" -> "
        int getCount() {
            return counter;
        }" |>;
(* Configure Arduino and upload the code. *)
DeviceConfigure[arduino, "Upload" -> {
    Initialization -> prependedCode,
    "Functions" -> <| "IncrementCounter" -> incrementCounter, 
      "GetCount" -> getCount  |>
    }];

Set up a scheduled task to increment the counter each 200 milliseconds:

(* Schedule a counter increment each every 200 milliseconds. *)
RunScheduledTask[DeviceExecute[arduino, "IncrementCounter"], 0.2];

And then query the Arduino for the counter whenever:

(* Get the current count. *)
DeviceExecute[arduino, "GetCount"]

And close the connection once done:

DeviceClose[arduino];
| improve this answer | |
$\endgroup$
  • $\begingroup$ Your WM code for loading sketch hangs on my system. $\endgroup$ – Jose Enrique Calderon Dec 21 '18 at 13:22
1
$\begingroup$

Close the serial monitor from the Arduino sketch. This captures the serial port and will not allow communication to the Mathematica kernel. Also, are you sure about comm8? This port number looks unusually high port number.

Depending on the versions of Mathematica, use the DeviceOpen[] to verify that the Mathematica is connecting to the device. But this function is available from version 10.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Hi, sorry, I should have been more clear in my OP: I closed the serial monitor before trying the MMa program, I mentioned the serial monitor because the fact that the MMa program gives a different response when it's open reflects that the COM8 port is almost certainly correct. I'll edit it to reflect this. $\endgroup$ – YungHummmma Oct 24 '16 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.