how to let 2 continues loops work at the same time

hello,

we have a problem and we could use some help with it.
we are working on a school project with the arduino, DCF77 and RFID.

the idea is to let de DCF77 constantly write de time and date to a LCD,
and at the same time de RFID has to check if a tag has been placed in front of it (when that happens a servo has to open a “door”) we have 2 servo’s and also an option for automatic log off of the pc the arduino is connected to.

all the programs work seperately but now we have to put them together.
but that doesn’t work, now if we load it into the arduino we have to put a tag above the RFID and then the time and name of the person shows on the pc (and time on the LCD (the user not jet)).

so the time doesn’t ceap writing to de LCD and the servo’s don’t turn anymore.

btw sorry for my bad english and the dutch comments in the programs.

here are the programs:

the RFID program:

#include <SoftwareSerial.h>
#include <string.h>
//RFID
int  val = 0; 
int bytesread = 0; 
//int i = 10; 
int result;
int result1;
int result2;
int result3;

char a_code[10]; 
char a_remco[] = "38002124FA";
char a_alex[] = "17007E7ED1";
char a_jorick[] = "17007E6EF4";
char a_kompanje[] = "38002247C5";


#define rxPin 7
#define txPin 6
// RFID reader SOUT pin connected to Serial RX pin at 2400bps to pin8

//SERVO

#include <Servo.h>
Servo deur1;  // create servo object to control a servo 
Servo deur2;  // a maximum of eight servo objects can be created 
int ranD;

int pos = 0;    // variable to store the servo position 


void setup()
{ 
  Serial.begin(9600);  // Hardware serial for Monitor 9600bps
  
//  pinMode(2,OUTPUT);       // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin 
//  digitalWrite(2, LOW);    // Activate the RFID reader 
deur1.attach(9);  // attaches the servo on pin 9 to the servo object 


}


void loop()
{

  SoftwareSerial RFID = SoftwareSerial(rxPin,txPin); 
  RFID.begin(2400);

  if((val = RFID.read()) == 10)
  {   // check for header 
    bytesread = 0; 
    while(bytesread<10)
    {  // read 10 digit code 
      val = RFID.read(); 
      if(val == 10)
      {  // if header or stop bytes before the 10 digit reading 
        break;                       // stop reading 
      } 
      a_code[bytesread] = val;      // add the digit
    //  Serial.println(val);
      bytesread++;                   // ready to read next digit  
    } 

    if(bytesread == 10)
    {  // if 10 digit read is complete 
    
     // Serial.print("TAG code is: ");   // possibly a good TAG 
     // Serial.println(a_code);            // print the TAG code
     
   
   
   
    result = memcmp(a_alex, a_code, 10);
   if( result == 0 ){
        Serial.println("alex");
      if (analogRead(1) <=500)
      {
       for(pos = 90; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
       {                                  // in steps of 1 degree 
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
       for(pos = 180; pos>=91; pos-=1)     // goes from 180 degrees to 0 degrees 
       {                                
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
      }
   }
   
   
   
   result1 = memcmp(a_code, a_remco, 10);
   if( result1 == 0){
     Serial.println("remco");
          if (analogRead(1) >=501)
      {
       for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 180 degrees 
       {                                  // in steps of 1 degree 
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
       for(pos = 90; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
       {                                
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
      }
   }
   
   
   
   
   
      result2 = memcmp(a_code, a_jorick, 10);
   if( result2 == 0){
     Serial.println("Jorick");
     if (analogRead(1) >=500)
      {
       for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 180 degrees 
       {                                  // in steps of 1 degree 
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
       for(pos = 90; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
       {                                
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
      }
      if (analogRead(1) <=501)
      {
       for(pos = 90; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
       {                                  // in steps of 1 degree 
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
       for(pos = 180; pos>=91; pos-=1)     // goes from 180 degrees to 0 degrees 
       {                                
         deur1.write(pos);              // tell servo to go to position in variable 'pos' 
         delay(15);                       // waits 15ms for the servo to reach the position 
       } 
      }
     
       
   }
   
      result3 = memcmp(a_code, a_kompanje, 10);
   if( result3 == 0){
     Serial.println("Kompanje");
   }
   
   if ((result != 0) && (result1 != 0) && (result2 != 0) && (result3 != 0)){
     Serial.println("Invalid");
   }
    bytesread = 0;  
    delay(1000);                       // wait for a second
  }
}
}

the DCF77 program

#include <LiquidCrystal.h>
#define DCF77PIN 2                     // Input for the DCF receiver
#define BLINKPIN 13                    // LED indicator output
#define DCF_split_millis 140           // Number of milliseconds before we assume a logic 1
#define DCF_sync_millis 1200           // No signal at second 59

// Definitions for the timer interrupt 2 handler
// The Arduino runs at 16 Mhz, we use a prescaler of 64 -> We need to 
// initialize the counter with 6. This way, we have 1000 interrupts per second.
// We use tick_counter to count the interrupts.
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 8);
#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
int tick_counter = 0;

struct DCF77Buffer {
  unsigned long long prefix      :21;
  unsigned long long Min      :7;      // minutes
  unsigned long long P1            :1;      // parity minutes
  unsigned long long Hour      :6;      // hours
  unsigned long long P2            :1;      // parity hours
  unsigned long long Day      :6;      // day
  unsigned long long Weekday      :3;      // day of week
  unsigned long long Month      :5;      // month
  unsigned long long Year      :8;      // year (5 -> 2005)
  unsigned long long P3            :1;      // parity
};

struct {
  unsigned char parity_flag      :1;
  unsigned char parity_min      :1;
  unsigned char parity_hour      :1;
  unsigned char parity_date      :1;
} flags;

 // Clock variables 
volatile unsigned char DCFSignalState = 0;  
unsigned char previousSignalState;
int previousFlankTime;
int bufferPosition;
unsigned long long dcf_rx_buffer;

// Time variables
volatile unsigned char ss;
volatile unsigned char mm;
volatile unsigned char hh;
volatile unsigned char day;
volatile unsigned char mon;
volatile unsigned int year;

unsigned char previousSecond;

// Initialize the DCF77 routines: initialize the variables,
// configure the interrupt behaviour.
void DCF77Init() {
  previousSignalState=0;
  previousFlankTime=0;
  bufferPosition=0;
  dcf_rx_buffer=0;
  ss=mm=hh=day=mon=year=0;
  pinMode(DCF77PIN, INPUT);
//Timer2 Settings: Timer Prescaler /64, 
  TCCR2B |= (1<<CS22);                    // turn on CS22 bit
  TCCR2B &= ~((1<<CS21) | (1<<CS20));     // turn off CS21 and CS20 bits   
// Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));   // turn off WGM21 and WGM20 bits 
  TCCR2B &= ~(1<<WGM22);                  // turn off WGM22
// Use internal clock - external clock not used in Arduino
  ASSR |= (0<<AS2);
  TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);     //Timer2 Overflow Interrupt Enable  
  RESET_TIMER2;
  attachInterrupt(0, int0handler, CHANGE);
}
// Append a signal to the dcf_rx_buffer. Argument can be 1 or 0. An internal
// counter shifts the writing position within the buffer. If position > 59,
// a new minute begins -> time to call finalizeBuffer().
void appendSignal(unsigned char signal) {
  dcf_rx_buffer = dcf_rx_buffer | ((unsigned long long) signal << bufferPosition);
  // Update the parity bits. First: Reset when minute, hour or date starts.
  if (bufferPosition ==  21 || bufferPosition ==  29 || bufferPosition ==  36) {
flags.parity_flag = 0;
  }
  // save the parity when the corresponding segment ends
  if (bufferPosition ==  28) {flags.parity_min = flags.parity_flag;};
  if (bufferPosition ==  35) {flags.parity_hour = flags.parity_flag;};
  if (bufferPosition ==  58) {flags.parity_date = flags.parity_flag;};
  // When we received a 1, toggle the parity flag
  if (signal == 1) {
    flags.parity_flag = flags.parity_flag ^ 1;
  }
  bufferPosition++;
  if (bufferPosition > 59) {
    finalizeBuffer();
  }
}

// Evaluates the information stored in the buffer. This is where the DCF77
// signal is decoded and the internal clock is updated.
void finalizeBuffer(void) {
  if (bufferPosition == 59) {
    struct DCF77Buffer *rx_buffer;
    rx_buffer = (struct DCF77Buffer *)(unsigned long long)&dcf_rx_buffer;
    if (flags.parity_min == rx_buffer->P1  &&
        flags.parity_hour == rx_buffer->P2  &&
        flags.parity_date == rx_buffer->P3) 
    { 
      //convert the received bits from BCD
      mm = rx_buffer->Min-((rx_buffer->Min/16)*6);
      hh = rx_buffer->Hour-((rx_buffer->Hour/16)*6);
      day= rx_buffer->Day-((rx_buffer->Day/16)*6); 
      mon= rx_buffer->Month-((rx_buffer->Month/16)*6);
      year= 2000 + rx_buffer->Year-((rx_buffer->Year/16)*6);
    }
  } 
  // reset stuff
  ss = 0;
  bufferPosition = 0;
  dcf_rx_buffer=0;
}
// Evaluates the signal as it is received. Decides whether we received
// a "1" or a "0" based on the 
void scanSignal(void){ 
    if (DCFSignalState == 1) {
      int thisFlankTime=millis();
      if (thisFlankTime - previousFlankTime > DCF_sync_millis) {
        finalizeBuffer();
      }
      previousFlankTime=thisFlankTime;
    } 
    else {
      /* or a falling flank */
      int difference=millis() - previousFlankTime;
      if (difference < DCF_split_millis) {
        appendSignal(0);
      } 
      else {
        appendSignal(1);
      }
    }
}
// The interrupt routine for counting seconds - increment hh:mm:ss.
ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  tick_counter += 1;
  if (tick_counter == 1000) {
    ss++;
    if (ss==60) {
      ss=0;
      mm++;
      if (mm==60) {
        mm=0;
        hh++;
        if (hh==24) 
          hh=0;
      }
    }
    tick_counter = 0;
  }
};

// Interrupthandler for INT0 - called when the signal on Pin 2 changes.
void int0handler() {
  // check the value again - since it takes some time to
  // activate the interrupt routine, we get a clear signal.
  DCFSignalState = digitalRead(DCF77PIN);
}

//LCD routines
void clearLCD()

{
  lcd.print(12, BYTE);
}

void startBigChars()
{
 lcd.print(2, BYTE);
}
// Dump the time to the serial LCD
void DumpTime(void){

// de dagen wegschijven naar het display
  if (day == 0) {
    lcd.setCursor( 0,1);
    lcd.print("00");

// tussen streepje plaatsen op display
    lcd.setCursor(2,1);
    lcd.print("-");
    }else{
      if (day <= 9){
        lcd.setCursor( 0,1);
        lcd.print("0");
        lcd.setCursor( 1,1);
        lcd.print(day, DEC);
      }else{
        lcd.setCursor( 0,1);
        lcd.print(day, DEC);
      }
      
// tussen streepje plaatsen op display
  lcd.setCursor(2,1);
  lcd.print("-");
  }   
  
// de maanden wegschijven naar het display
    if (mon == 0) {
    lcd.setCursor(3,1);
    lcd.print("00");

// tussen streepje plaatsen op display    
    lcd.setCursor(5,1);
    lcd.print("-");
  }else{
      if (mon <= 9){
        lcd.setCursor( 3,1);
        lcd.print("0");
        lcd.setCursor( 4,1);
        lcd.print(mon, DEC);
      }else{
        lcd.setCursor( 3,1);
        lcd.print(mon, DEC);
      }
      
// tussen streepje plaatsen op display
  lcd.setCursor(5,1);
  lcd.print("-");
  }

// de jaren wegschijven naar het display
  if (year == 0) {
    lcd.setCursor(6,1);
    lcd.print("0000");
  }else{
  lcd.setCursor(6,1);
  lcd.print(year, DEC);
  }


// de uren weergeven op het display
  if (hh == 0) {
    lcd.setCursor( 12, 1);
    lcd.print("00");
  }
    lcd.setCursor( 12, 1);
  if (hh <= 9) {
    lcd.print("0");
    lcd.setCursor( 13, 1);
    lcd.print(hh, DEC);
  }else{
    lcd.setCursor( 12, 1);
    lcd.print(hh, DEC);
  }
 
 // per seconde de : laten knipperen  
  if ((ss % 2) == 0) {
    lcd.setCursor( 14, 1);
    lcd.print(":");
  } else {
    lcd.print(" ");
  }
  
// de minuten weergeven op het display  
  if (mm == 0) {
    lcd.setCursor( 15, 1);
    lcd.print("00");
  }
    lcd.setCursor( 15, 1);
  if (mm <= 9) {
    lcd.print("0");
    lcd.setCursor( 16, 1);
    lcd.print(mm, DEC);
  }else{
    lcd.setCursor( 15, 1);
    lcd.print(mm, DEC);
  }
  
// per seconde de : laten knipperen  
  if ((ss % 2) == 0) {
    lcd.setCursor( 17, 1);
    lcd.print(":");
  } else {
    lcd.print(" ");
  }
  
// secondes weergeven op display
  if (ss == 0) {
    lcd.setCursor( 18, 1);
    lcd.print("00");
  }
    lcd.setCursor( 18, 1);
  if (ss <= 9) {
    lcd.print("0");
    lcd.setCursor( 19, 1);
    lcd.print(ss, DEC);
  }else{
    lcd.setCursor( 18, 1);
    lcd.print(ss, DEC);
  }

// alles weergeven in arduino programma op pc
  Serial.print(day,DEC);
  Serial.print("-"); 
  Serial.print(mon,DEC); 
  Serial.print("-"); 
  Serial.print(year,DEC); 
  
  Serial.print("   ");     
  
  Serial.print(hh,DEC);
  Serial.print(":");  
  Serial.print(mm,DEC);
  Serial.print(":");  
  Serial.print(ss,DEC); 
  
  Serial.print("   ");  
  
  Serial.println(digitalRead(DCF77PIN));
}

// Standard Arduino methods below.
void setup(void) {
  // We need to start serial here again, 
  // for Arduino 007 (new serial code)
  Serial.begin(9600);
  clearLCD();
  DCF77Init();
  
}

void loop(void) {
     
  if (ss != previousSecond) {
    DumpTime();
    previousSecond = ss;
  }
  if (DCFSignalState != previousSignalState) {
    scanSignal();
    
    if (DCFSignalState) {
      digitalWrite(BLINKPIN, HIGH);
    } else {
      digitalWrite(BLINKPIN, LOW);
    }
    previousSignalState = DCFSignalState;
  }
}

OK, first move your RFID setup into "setup ()" (just for consistency)

Now the thing to remember is that using the software serial libraries, a "read" will wait until it has read something.

So that makes reading your RFID a little harder because it will block LCD updates, unless you move the serial line to a hardware serial input, or you've got a "data ready" type signal from your RFID reader, that you can use to signal that you should be calling the "read" routine.

You may be able to attach an interrupt to the serial Rx pin, to detect the start of some data coming in.

oke I understand what you mean but than again how do you do that? I have already searched the internet for examples and some explanation about how to use interrupts but I didn't really understand the things that I've found. can you give us an example for a simple way of making an interrupt to the serial Rx pin. (or just a way to use an interrupt overall)

(on school we haven't learned anything about using interrupts jet ( we have to find out everything for ourselves)).

Interrupts in a nutshell.

Interrupts are just signals (usually hardware, though there are software interrupts too) that tell the processor that something has happened.

If the processor has enabled the interrupt, it will stop when it has finished executing the current instruction, remember where it was and what it was doing, and go off and execute a specific routine called the interrupt service routine. It will also sometimes disable other interrupts of lower importance/priority

When the processor has finished executing the interrupt service routine, it retrieves the status of what it was doing before, and carries on with the next instruction as though nothing had happened.

Interrupts may be triggered by the edge of the signal, or the level of a signal. Note that if you trigger on edges, and interrupts are disabled when the interrupt occurs, the processor may miss the interrupt, even when interrupts are later reenabled.

There are rules and guidlines about what you should and shouldn't do in interrupt service routines. You should do as little as possble, to maximise responsiveness, so don't do things like "delay" or serial I/O in a service routine.

http://www.arduino.cc/en/Reference/AttachInterrupt

I can't say whether or not interrupts would work with the software serial libraries - it isn't something I've tried. You'd probably want to enable them to detect the start bit, disable them during reception, and then reenable them after the stop-bit.

Maybe someone else has some ideas?