Generally, I need to connect my Arduino Uno to Mathematica and read 3 analog values from A0, A1, A2 in real-time.

As I understand, I have 2 ways of connecting Arduino to Mathematica:

First: I have a properly working Arduino IDE sketch that can be uploaded to the device from Mathematica (without using Arduino IDE) somehow like they do on this page - http://community.wolfram.com/groups/-/m/t/936358

My particular working Arduiono IDE sketch is:

    int raw1 = 0, raw2 = 0, raw3 = 0;
    int x = 0, y1 = 0, y2 = 0, y3 = 0;

    void setup() 
    pinMode( A0, INPUT );
    pinMode( A1, INPUT );
    pinMode( A2, INPUT );

    void loop() 
    while (x<=6000)
    raw1 = analogRead( A0 );
    raw2 = analogRead( A1 );
    raw3 = analogRead( A2 );
    Serial.print( y1 );
    Serial.print( y2 );
    Serial.print( y3 );

Second: There are some commands in Wolfram Language that allow to communicate with my Arduino Uno without using Arduino IDE language. As I understand, my code in Wolfram language should be something like this (this program is supposed to read 3 values every 0.01 second for 1 second):

    Uno = DeviceOpen["Arduino", "COM3"];

    DeviceConfigure[Uno, <|"A0" -> "AnalogInput", "A1" -> "AnalogInput", "A2" -> "AnalogInput"|>];

    DeviceReadTimeSeries[Uno, {1, 0.01}, {"A0", "ReadMode" -> "Analog"}]
    DeviceReadTimeSeries[Uno, {1, 0.01}, {"A1", "ReadMode" -> "Analog"}]
    DeviceReadTimeSeries[Uno, {1, 0.01}, {"A2", "ReadMode" -> "Analog"}]


Nevertheless, Mathematica doesn't compile this and gives such an error report:

    CCompilerDriver`CreateObjectFile::cmperr: Compile error: avr-g++: error:C:\Users\Username\AppData\Local\Temp\arduinocompile1420c72c8f614b19b9df9d5891fcf275\SketchTemplate.cpp.c: No such file or directory

What is the problem? Many thanks for any hint!

P.S. I use Mathematica 11.

P.P.S. Have attached the code we're discussing in the comments Here it is

  • $\begingroup$ The file name SketchTemplate.cpp.c (cpp and c extenstion) looks a bit suspicious. $\endgroup$ – user21 Nov 27 '17 at 11:32

I think the second approach should work. If it's not working for you, try the following with the first approach.

First, you need to fix the sketch by specifying the type of the variables y1, y2, and y3.

After uploading your sketch, open a connection to the Arduino.

dev = DeviceOpen["Serial", "COM3"]

Create a function to parse the incoming data.

parseData[{val1__, 9, val2__, 9, val3__}] := 
   ToExpression@FromCharacterCode@# & /@ {{val1}, {val2}, {val3}}
parseData[___] := Sequence[]

And set up a task to read the data.

rawReadings = {};
task = SessionSubmit@
   ScheduledTask[AppendTo[rawReadings, DeviceReadBuffer[dev, "ReadTerminator" -> 10]], 0.2]

Now you should be able to plot the values.

ListLinePlot[Transpose[parseData /@ rawReadings], PlotLegends -> Automatic]// Dynamic

When you are done, remove the task and close the connection.


My results:

On a Arduino Uno, I connected A0 to GND, and A1 and A2 to two potentiometers.

enter image description here

  • $\begingroup$ Thanks a lot for Your feedback! But my Mathematica 11 doesn't recognize SessionSubmit and TaskRemove. Basically, this is what I get as an output: ListLinePlot::lpn: Transpose[{}] is not a list of numbers or pairs of numbers. And parseData /@ rawReadings gives back nothing when evaluated in place. $\endgroup$ – Aleksandr Berezutskii Nov 27 '17 at 23:48
  • $\begingroup$ Could you remove SessionSubmit and try RunScheduledTask instead of ScheduledTask. And in the end you will need to use RemoveScheduledTask instead of TaskRemove. $\endgroup$ – Suba Thomas Nov 28 '17 at 0:13
  • $\begingroup$ Yes, that partly works out, but nevertheless, the error ListLinePlot::lpn: Transpose[{}] is not a list of numbers or pairs of numbers doesn't go away, so it should be something wrong with the function - it returns an empty list. $\endgroup$ – Aleksandr Berezutskii Nov 28 '17 at 5:19
  • $\begingroup$ Also, should I upload the sketch from Arduino IDE and then close it or forget about Arduino IDE at all? Is there an algorithm which can tell one what to do in what order? $\endgroup$ – Aleksandr Berezutskii Nov 28 '17 at 7:56
  • 1
    $\begingroup$ @JoseECalderon, ToCharacterCode["\t"] is where the 9 comes from. That is because the OP used \t to separate his values. $\endgroup$ – Suba Thomas Jan 12 '19 at 21:33

I am retaking the original subject of your question around why is option number 1 not compiling.

From inspection at your error messages

CCompilerDriver`CreateObjectFile::cmperr: Compile error: avr-g++: error:C:\Users\Username\AppData\Local\Temp\arduinocompile1420c72c8f614b19b9df9d5891fcf275\SketchTemplate.cpp.c: No such file or directory

shows an indication that you do not have a current C++ compiler with the necessary libraries. I am assuming you are using a Windows OS because your COM3 port is formatted for Windows O.S. You also mentioned that your Mathematica 11 doesn't recognize SessionSubmit and TaskRemove

Your compiler error is looking for a avr g++ compiler. In the end days of v10 and early days of v11, Mathematica was limited to C compilers provided by Visual Studio 12 or earlier. I am suspecting that you have not installed a recent Visual Studio into your computer. This will rendered many of the functions based on Universal Windows Platform stranded.

It is a good idea to install a recent version of Visual Studio and include all the SDK libraries. There is a post on this subject that will help you on this. https://mathematica.stackexchange.com/a/172717/11974 . Is is possible that you may have to reinstall WM afterward to endure that all variable system path are properly recorded

Also , will like to comment on option 2. Must people do not realized that the WM Arduino functions as shown in your application Uno = DeviceOpen["Arduino", "COM3"];throws away your loaded sketch. Mathematica will load its own version of a Firmata based protocol which controls communication with the device. Therefore, even though you uploaded option 1 sketch, when engaging the DeviceOpen["Arduino".... override your sketch.

I have to acknowledge that the answer from @Suba Thomas is the best way to go and deserves full upvote. His code offers a path for full control of the device. Even more, will work on any pin from any of the other Arduino Boards and not limited to an Arduino Uno.


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.