Go Down

Topic: bidirectional serial communication:simultaneous sensor readout and motor control (Read 3385 times) previous topic - next topic

Scratch

Hello,
I am a Newbie regarding Arduino.  :~
Nevertheless I am trying to use an Arduino Uno to both collect data from 4 force sensors continuously and in the meantime turn on and off a seperate drive unit. Till now I am only able to read the data of the force sensors during the motor is running. In a second step I managed to read the sensor data seperately and continuously but could not include the motor control.
Does anybody have an idea or a hint helping with this?
Thank you in advance
Scratch

AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

retrolefty

Post your code and I'm sure someone here can help improve it. Be sure to use the # edit button to embed the sketch code.

Lefty

tkbyd

There's lots on serial comms with Arduinos talking to other devices at....

http://sheepdogguides.com/arduino/art4SeIntro.htm

Scratch

I already tried to help myself using the forum mentioned by tkbyd. But I couldn't succeed.
I tried to use the SimpleMessageSystem as you can see here:

Code: [Select]


#include <SimpleMessageSystem.h>

//pin-setup
void setup() {
  pinMode(10, OUTPUT);
  Serial.begin(9600); 
  establishContact();
}

//wait for contact...
void establishContact() {
  while (Serial.available() <= 0)
  {delay(300);}
}

int F[4]= {0,0,0,0}; //sensordaten
long unsigned time=0; //zeitachse

//---------------------- Data acquisition ----------------------------//

void acqui(){ //acquisition
  while(1){
    delay(100); //
    F[0]=map(analogRead(0),1,1024,0,800); //kalibration des sensors
    F[1]=map(analogRead(1),1,1024,0,800); //kalibration des sensors
    F[2]=map(analogRead(2),1,1024,0,800); //kalibration des sensors
    F[3]=map(analogRead(3),1,1024,0,800); //kalibration des sensors

    Serial.print(millis()-time); //real time
    Serial.print(" ");
    Serial.print(F[0]);
    Serial.print(" ");
    Serial.print(F[1]);
    Serial.print(" ");
    Serial.print(F[2]);
    Serial.print(" ");
    Serial.println(F[3]);
  }
}

//---------------------- machine function----------------------------//
void machine(long int t){ //acquisition
  digitalWrite(10,1); //start the machine
  int stopper=0;
  while(1){
    if((millis()-time)>t){stopper++;}
    if(stopper>2){break;}
  }
  digitalWrite(10,0); //stop the machine
}

//---------------------- main loop----------------------------//
void loop() {
  time = millis();
  long int duration = 0;
   
  if (messageBuild() > 0) { // Checks to see if the message is complete and erases any previous messages
    switch (messageGetChar()) { // Gets the first word as a character
    case 'a':
      acqui();
    case 'm':
      duration = messageGetInt();
      machine(duration*1000);
      duration=0;
    }
  }
}



So if somebody could help me, I would really appriciate it.

AWOL

Code: [Select]
case 'a':
      acqui();
    case 'm':

Is there a missing "break", or is the fall-though intentional?

(Telling us "But I couldn't succeed" isn't helping us to help you - you need to tell us what it is doing that it should not, or what it is not doing that it should.)
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Scratch

The main problem is that I'm not able to acquire the sensor data continously and to start/stop the motor using the two commands 'a' and 'm'.

In case 'm' I indeed should add a break.

Thank you

AWOL

But what about case 'a'?

What is "duration" in "loop" meant to do?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Scratch

case 'a' should be running continuously till I'll terminate the program. Do you think I should a break also in this case?

AWOL

Quote
case 'a' should be running continuously till I'll terminate the program.

Which it will, because "acqui" is an infinite loop.
Sorry, missed that.
Maybe the comments could make that clear that that was what you intended.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
In a second step I managed to read the sensor data seperately and continuously but could not include the motor control.

Is this because acqui() never returns?

Scratch

What exactly do you mean with
Quote
Is this because acqui() never returns?
?

The objective is to acquire data over a long time period (about 3 weeks) and turn the motor on/off for defined durations within a defined break in between leading to a on-off-on-off profile with 30 min-24h -30 min -24h as an example. Maybe I started the whole thing in a wrong way?

Could it be easier to create two subroutines; one acquiring the sensor data and a second one turning the motor on/off. In this case I even could adapt the data acquisition rate to lower frequency for motro off states and higher ones during motor on.

Would this be feasible for example using a code like this:

Code: [Select]

//pin-setup
void setup() {
  pinMode(10, OUTPUT);
  Serial.begin(9600); 
  establishContact();
}

//wait for contact...
void establishContact() {
  while (Serial.available() <= 0) {
    delay(300);
    }
}


int F[4]= {0,0,0,0}; //sensor data
long unsigned time=0; //time axis




//---------------------- data ----------------------------//

void data(){ //acquisition
   while(1){
     delay(5000); //Data rate   
     F[0]=map(analogRead(0),1,1024,0,800); //sensor calibration
     F[1]=map(analogRead(1),1,1024,0,800); //sensor calibration
     F[2]=map(analogRead(2),1,1024,0,800); //sensor calibration
     F[3]=map(analogRead(3),1,1024,0,800); //sensor calibration

    Serial.print(millis()-time); //real time
    Serial.print(" ");
    Serial.print(F[0]);
    Serial.print(" ");
    Serial.print(F[1]);
    Serial.print(" ");
    Serial.print(F[2]);
    Serial.print(" ");
    Serial.println(F[3]);
   
  }
}

//---------------------- motor function ----------------------------//

void aqui(long int t){ //acquisition
  digitalWrite(10,1); //start the motor
  int stopper=0;
  while(1){
     delay(50); //Data rate   
     F[0]=map(analogRead(0),1,1024,0,800); //sensor calibration
     F[1]=map(analogRead(1),1,1024,0,800); //sensor calibration
     F[2]=map(analogRead(2),1,1024,0,800); //sensor calibration
     F[3]=map(analogRead(3),1,1024,0,800); //sensor calibration

    Serial.print(millis()-time); //real time
    Serial.print(" ");
    Serial.print(F[0]);
    Serial.print(" ");
    Serial.print(F[1]);
    Serial.print(" ");
    Serial.print(F[2]);
    Serial.print(" ");
    Serial.println(F[3]);
   
    if((millis()-time)>t){stopper++;}
    if(stopper>2){break;}
       
    }
   
  digitalWrite(10,0); //stop the machine
  }


//---------------------- String functionen ----------------------------//
char c=' ';
char str[10]; //String for parse

//empty string
void clstr(void){
     for(int n=0;n!=10;n++){
      str[n]=' ';
     }
  }

//read String
int strin(void){//check serial data acquisition
//only works if string available

  delay(20); //time fram between port connections
  if (Serial.available()){ 
    clstr(); //empty string
 
    int i=0;
    while(Serial.available()){str[i]=Serial.read();
      if(str[i]=='\n'){break;}
      i++;
      } 
    return(i);
    }
  else{return(0);} 
  }

long int readvalue(void){
  return(atol(str)); //convert to int
  }

int Z=0;
long int duration=0;


//---------------------- Hauptschleife ----------------------------//
void loop() {
    time = millis();
    data();
     Z=strin();
          //if input for duration was received
     if(Z){
       duration=readvalue();
       aqui(duration*1000);
       duration=0;
       Z=0;
       }
       
       //if not input was received
if(!Z){digitalWrite(10,0);} //stop the machine
       }
         


In this case I'm still lacking the possibility to start the motor by sending another number...

Scratch

So now I managed to have a system reading the values and allowing at the same time to turn the motor on/off. This was obtained using the code above removing the while loop in data().
The only problem I still have is the "time stamp". Every time the motor starts a new time stamp is created also each data ponit during data() has the time stamp of the delay (5000 ms). I would like to have a continuous time running from the initioation of the programm till the termination performed by the user. Is this possible? Or would you reccommend, since I'm going to use LabView to readout and store the data, to use LabView to clear the time problem?

Thank you for your help!

AWOL

Quote
What exactly do you mean with
Quote
Is this because acqui() never returns?

Exactly that; there is an infinite loop in "acqui" with no "break" - I wouldn't be surprised if the compiler had optimised-out the "return" instruction.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Genesisfactor

I know this is old, but, there is a concurrency project for Arduino at http://www.concurrency.cc/.  It seems interesting, as i too will require some programming that demand simultaneous events and processes running.  There is a change in the programming language, and i'm not sure hot the libraries ill function, but they have a servo motor example in the downloadable book.

Go Up