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$
  • $\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$ – Dr. belisarius Oct 6 '14 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$ –  EDDYSAMA Oct 6 '14 at 20:12
  • $\begingroup$ Please join me in chat chat.stackexchange.com/rooms/17666/arduino $\endgroup$ – Dr. belisarius Oct 6 '14 at 21:29
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$

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.