Message Boards Message Boards

Arduino and Mathematica 10 (Can't make a ListPlot from an analogread)

Posted 10 years ago

Hello everybody first of all, sorry of my English. I am trying to connect Arduino Mega with Mathematica 10. The Arduino Boar is programmed to read every 200 ms an analog port, print its value on the serial with the corresponding time just to make a ListPlot. I could do it with an older version of Mathematica but now I would like to use de new Serial Link library. This is the Arduino Code:

float tiempo = 0.0;
int A = 0;
void setup() {
  Serial.begin(115200);
}

void loop() {
  tiempo = millis()/1000.0;
  int sensorValue = analogRead(A0);

  if (Serial.available() > 0) {
    // get incoming byte:
    int letra = Serial.read();
    if (letra == 'T'){
      A=1;
    }
    if (letra == 'S'){
      A=0;
    } 
  }

  if (A == 1){
    Serial.print("{");
    Serial.print(tiempo);
    Serial.print(" , ");
    Serial.print(sensorValue);
    Serial.println("}");
  }

  delay(200);       
}

The Loop starts when Mathematica writes “T” on the Serial and finishes when writes “S” on the serial Port.

 Mathematica code:

Mathematica receive every data and store it, but I can't Plot beause I have problems with commas:

Problem with commas

I have a similar code on Mathematica 9 working fine. Can you help me please?

Thanks!!!

Attachments:
6 Replies

Thank you!!

Hi everybody, first of all thanks for your time and help, you are very helpful!!!. Ian, your code is correct, but this not exactly what I was looking for. I want to make a ListPlot while receiving the information, not when I press “Shift+enter”, so I tried with your code and the “Dynamic” option but I cannot do it. On the other hand, also I would like to make severals Plots corresponding to several sensors in real time.

Again, thanks for your help.

Fernando.

So what you need is to be able to read in from the Serial port as a stream, and from multiple ports concurrently? I will just say that this is still an "unsolved" problem in Mathematica with Serial ports, as this requires asynchronous updating of the dynamics, which doesn't really work well in my experiences. I think the best solution would be to have the Arduino spit out the values in some form of packet, something similar to the following:

\n a { 1 , 10 } \n b { 1 , 12 } \n c { 1 , 13 } 

Where the \n (newline) delimiter will still allow you to split the values up by each reading, but then the 'a', 'b', 'c', etc. characters allow you to distinguish between which port the reading is coming from, so you could do something like the following:

RunScheduledTask[
 (
  rawdata = DeviceReadBuffer["Serial"];
  individualPointsStringList = StringSplit[FromCharacterCode[rawdata], "\n"];
  sortedPointsList = GatherBy[individualPointsStringList, StringTake[#, 1] &];
  cleanFullPointsList = ToExpression /@ (StringDrop[#, 1] & /@ sortedPointsList);
  AppendTo[sensorAPointsList,cleanFullPointsList[[1]]];
  AppendTo[sensorBPointsList,cleanFullPointsList[[2]]];
  )]

Etc. for all the sensors you have connected to your Arduino. This would make the variables sensorAPointsList, etc. have all the values you need and would be updated every one second. You can look at the documentation page for RunScheduledTask to change the timing if you want this to be updated sooner.

Now, with the following dynamic, we can set up a live plot of the sensor values with the following.

Dynamic[Row[{
     ListLinePlot[sensorAPointsList,ImageSize->{250,250}], 
     ListLinePlot[sensorBPointsList,ImageSize->{250,250}]}]]

For me, this produced the following graphs: Graph of Arduino plots

POSTED BY: Ian Johnson

Thank you Ian. Would you mind posting your complete Arduino sketch and Mathematica notebook?

I think that the problem here is that the Arduino is spitting out over serial something that looks like "{ 123, 1233} \n { 456, 789 } \n " so when you go to plot that, it doesn't automatically evaluate to the list of lists that you want, and stays as Vitaliy points out in String format. So if you split it by the newline character and use ToExpression I think that should work for you.

When I uploaded your sketch to my Arduino, the following worked for me.

rawdata = DeviceReadBuffer["Serial"]
points = ToExpression /@ StringSplit[FromCharacterCode[rawdata], "\n"]
ListLinePlot[points]

That gave me what I think you are looking for.

Plot from the Arduino

Ian

POSTED BY: Ian Johnson

FromCharacterCode returns a string, not (lists of) numbers. ListPlot cannot plot strings.

POSTED BY: Vitaliy Kaurov
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract