7
$\begingroup$

I'm trying to take 5 analog reads from two or more Arduinos at different times. So to do that my listening port via xbee is COM8, then I start a RunScheduledTask sending a # to the COM port which activates the first Arduino. The Arduino in turn sends data back from 5 "sensors" using this format number1#number2#number3#number4#number5/n. Mathematica reads that and when encounters /n saves that string in a variable called dato. This is repeating every .25 seconds. Thenn I split the string and change from char to integer in this format {111, 222, 333, 444, 555}

It is working for one Arduino, but I would like to connect a second one by sending the character $.

And also - is there a way to speed those things up ? Communication between slaves is not an option as this results in bad measurements.

xbee = DeviceOpen["Serial", {"COM8", "BaudRate" -> 9600}]

RemoveScheduledTask /@ ScheduledTasks[];

RunScheduledTask[DeviceWriteBuffer[xbee, "#"]; 
  dato = FromCharacterCode[
    DeviceReadBuffer[xbee, "ReadTerminator" -> "\n"]], .25];
Dynamic[grafica1 = StringSplit[dato, "#"]]

a = {AngularGauge[
    Dynamic[temperatura = ToExpression[grafica1[[1]]]], {0, 2000}, 
    GaugeLabels -> Automatic]
   AngularGauge[
    Dynamic[humedad = ToExpression[grafica1[[2]]]], {0, 2000}, 
    GaugeLabels -> Automatic]
   AngularGauge[
    Dynamic[monoxido = ToExpression[grafica1[[3]]]], {0, 2000}, 
    GaugeLabels -> Automatic]
   AngularGauge[
    Dynamic[dioxido = ToExpression[grafica1[[4]]]], {0, 2000}, 
    GaugeLabels -> Automatic]
   AngularGauge[
    Dynamic[sulfuro = ToExpression[grafica1[[5]]]], {0, 1000}, 
    GaugeLabels -> Automatic]}

the Arduinos side

1st Arduino

int tempsen = A0;
int humsen  = A1;
int gas1sen = A2;
int gas2sen = A3;
int gas3sen = A4;
int temperatura,huemdad,gas1,gas2,gas3 = 0;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while( Serial.available() == 0);
  char data = Serial.read();
  if  (data == '#')
  {
    delay (1);*/
    int temperatura = map(analogRead(tempsen), 0, 1023, 0, 1000);
    Serial.print(temperatura);
    Serial.print('#');
    delay (1);
    int humedad = map(analogRead(humsen), 0, 1023, 0, 1000);
    Serial.print(humedad);
    Serial.print('#');
    delay(1);
    int gas1 = map(analogRead(gas1sen), 0, 1023, 0, 1000);
    Serial.print(gas1);
    Serial.print('#');
    delay(1);
    int gas2 = map(analogRead(gas2sen), 0, 1023, 0, 1000);
    Serial.print(gas2);
    Serial.print('#');
    delay(1);
    int gas3 = map(analogRead(gas3sen), 0, 1023, 0, 1000);
    Serial.println(gas3);
    delay(1);
    Serial.flush();
  }
  else{ 
    delay(500);
    Serial.flush();
  }
  Serial.flush();
}

2nd Arduino

int tempsen = A0;
int humsen  = A1;
int gas1sen = A2;
int gas2sen = A3;
int gas3sen = A4;
int temperatura,huemdad,gas1,gas2,gas3 = 0;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while( Serial.available() == 0);
  char data = Serial.read();
  if  (data == '$')
  {

    delay (1);*/
    int temperatura = map(analogRead(tempsen), 0, 1023, 0, 1000);
    Serial.print(temperatura);
    Serial.print('$');
        delay (1);
        int humedad = map(analogRead(humsen), 0, 1023, 0, 1000);
        Serial.print(humedad);
        Serial.print('$');
    delay(1);
    int gas1 = map(analogRead(gas1sen), 0, 1023, 0, 1000);
    Serial.print(gas1);
    Serial.print('#');
    delay(1);
    int gas2 = map(analogRead(gas2sen), 0, 1023, 0, 1000);
    Serial.print(gas2);
    Serial.print('$');
    delay(1);
    int gas3 = map(analogRead(gas3sen), 0, 1023, 0, 1000);
    Serial.println(gas3);
    delay(1);
    Serial.flush();
  }
  else{ 
    delay(500);
    Serial.flush();
 }   
Serial.flush();
 }

I made this mini network with 3 xbees - one master and two slaves with the following restrictions. Slaves only communicate with the master and no "slave to slave" communication is allowed.

$\endgroup$
3
  • $\begingroup$ Since DeviceReadBuffer is a blocking function, what prevents you from writing the second polling char to the port after capturing the first read? Sorry, can test the code code here. $\endgroup$ Commented Oct 6, 2014 at 12:22
  • $\begingroup$ at this point the mathematica code does what i spected, my problem is if I send the other character IT begean to be noisy. I guess I have to make a fuction that let me switch between "$" and "#" and I have no idea yet ( second day at programig in mathematica ) after that ill need to save incoming data from both devices in a .CSV file :( $\endgroup$ Commented Oct 6, 2014 at 20:12
  • $\begingroup$ Please join me in chat chat.stackexchange.com/rooms/17666/arduino $\endgroup$ Commented Oct 6, 2014 at 21:29

2 Answers 2

2
$\begingroup$

Probably better (Warning, untested code ... I don't have any Arduino around)

xbee = DeviceOpen["Serial", {"COM8", "BaudRate" -> 9600}]
RemoveScheduledTask /@ ScheduledTasks[];
lista1 = lista2 = {};
counter = 0;
(* getPoll should include code for the interface error management *)
getPoll[char_, int_] := 
       (DeviceWriteBuffer[int, char]; 
       {Join[DateList[], {FromCharacterCode[ DeviceReadBuffer[int, "ReadTerminator" -> "\n"]]}]})

(* generalizing for n Arduinos could be easier if each Arduino answers to a 
   numeric polling address *)

RunScheduledTask[
 AppendTo[lista1, getPoll["#", xbee]];
 AppendTo[lista2, getPoll["$", xbee]];
 If[Mod[ ++counter, 100] == 0,
  (Export["yourfile" <> "-lista1-" <> ToString@counter <> ".CSV", lista1]; 
   Export["yourfile" <> "-lista2-" <> ToString@counter <> ".CSV", lista2];
   lista1 = lista2 = {};)]
 , 5]
$\endgroup$
1
$\begingroup$

thanks to belisarius we improved the mathemathica code this way and it works just fine .. hopely we can improve it even more ...

saludos desde Mexico

xbee = DeviceOpen["Serial", {"COM8", "BaudRate" -> 9600}]
RemoveScheduledTask /@ ScheduledTasks[];

lista1 = {};
lista2 = {};

RunScheduledTask[
 DeviceWriteBuffer[xbee, "#"]; 
 dato1 = FromCharacterCode[
   DeviceReadBuffer[xbee, "ReadTerminator" -> "\n"]]; 
 DeviceWriteBuffer[xbee, "$"];
 dato2 = FromCharacterCode[
   DeviceReadBuffer[xbee, "ReadTerminator" -> "\n"]]; 
 AppendTo[lista1, Join[DateList[], {dato1}]]; 
 AppendTo[lista2, Join[DateList[], {dato2}]], 5]

Dynamic[grafica1 = StringSplit[dato1, "."]]
Dynamic[grafica2 = StringSplit[dato2, "."]]

If[Length[grafica1] == 5,
 AngularGauge[
   Dynamic[temperatura1 = ToExpression[grafica1[[1]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[humedad1 = ToExpression[grafica1[[2]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[monoxido1 = ToExpression[grafica1[[3]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[dioxido1 = ToExpression[grafica1[[4]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[sulfuro1 = ToExpression[grafica1[[5]]]], {0, 1000}, 
   GaugeLabels -> Automatic]]

If[Length[grafica2] == 5,
 AngularGauge[
   Dynamic[temperatura2 = ToExpression[grafica2[[1]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[humedad2 = ToExpression[grafica2[[2]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[monoxido2 = ToExpression[grafica2[[3]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[dioxido2 = ToExpression[grafica2[[4]]]], {0, 2000}, 
   GaugeLabels -> Automatic]
  AngularGauge[
   Dynamic[sulfuro2 = ToExpression[grafica2[[5]]]], {0, 1000}, 
   GaugeLabels -> Automatic]]

in the 1° arduino side

int tempsen = A0;
int humsen  = A1;
int gas1sen = A2;
int gas2sen = A3;
int gas3sen = A4;
int temperatura,huemdad,gas1,gas2,gas3 = 0;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while( Serial.available() == 0);
  char data = Serial.read();
  if  (data == '$')
  {

    delay (1);
    int temperatura = map(analogRead(tempsen), 0, 1023, 0, 1000);
    Serial.print(temperatura);
    Serial.print('.');
    delay (1);
    int humedad = map(analogRead(humsen), 0, 1023, 0, 1000);
    Serial.print(humedad);
    Serial.print('.');
    delay(1);
    int gas1 = map(analogRead(gas1sen), 0, 1023, 0, 1000);
    Serial.print(gas1);
    Serial.print('.');
    delay(1);
    int gas2 = map(analogRead(gas2sen), 0, 1023, 0, 1000);
    Serial.print(gas2);
    Serial.print('.');
    delay(1);
    int gas3 = map(analogRead(gas3sen), 0, 1023, 0, 1000);
    Serial.println(gas3);
    delay(1);
    Serial.flush();
  }
  else{ 
    delay(500);
    Serial.flush();
  }
  Serial.flush();
}

in the 2° arduino side

int tempsen = A0;
int humsen  = A1;
int gas1sen = A2;
int gas2sen = A3;
int gas3sen = A4;
int temperatura,huemdad,gas1,gas2,gas3 = 0;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while( Serial.available() == 0);
  char data = Serial.read();
  if  (data == '#')
  {

    delay (1);
    int temperatura = map(analogRead(tempsen), 0, 1023, 0, 1000);
    Serial.print(temperatura);
    Serial.print('.');
    delay (1);
    int humedad = map(analogRead(humsen), 0, 1023, 0, 1000);
    Serial.print(humedad);
    Serial.print('.');
    delay(1);
    int gas1 = map(analogRead(gas1sen), 0, 1023, 0, 1000);
    Serial.print(gas1);
    Serial.print('.');
    delay(1);
    int gas2 = map(analogRead(gas2sen), 0, 1023, 0, 1000);
    Serial.print(gas2);
    Serial.print('.');
    delay(1);
    int gas3 = map(analogRead(gas3sen), 0, 1023, 0, 1000);
    Serial.println(gas3);
    delay(1);
    Serial.flush();
  }
  else{ 
    delay(500);
    Serial.flush();
  }
  Serial.flush();
}
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.