A complete Arduino based timing controller system

Hello,

back in 2012-2013 I developed a relatively simple system for performing precise timing control using arduino.
I used 2 arduini mega and 1 arduino nano, 1 for touch screen I/O, 1 for timing controls and the nano for a liquid detector.

You can find all the code in the supplementary material of the afforementioned publication,
and I would be happy to explain further.

The reason for this post is that I think a complete application like this could be helpful to a broader audience than the specific audience of magnetic resonance spectroscopy / NMR / DNP etc.

Interesting project! Thanks!

Hello sotirisk
I would like to get a copy of your precise timing code..you post in arduino forum but didn't involve the code

sotirisk:
You can find all the code in the supplementary material of the afforementioned publication,

can you have access to the paper?

I use the link in your post then redirect me back to the post

Hi guys, sorry for this really delayed answer.
If it makes any sense after 2 years, this is the code:
(it's based on the switch case statement - not something fancy, but does the job).
Last upgrade is from 2013, but as I am reusing it now, I can help if something is not clear.
Now take care of the signal levels, if you are using 2 arduini as I did, 5v TTL serial will work, but
if you connect a pc RS232 serial it will certainly do not. I am not sure of the voltage level of a raspberry (I only own 1 raspberry used with my 3d printer and never tried arduino <-> raspberry), but I assume if you use a USB->serial it will not work, you need to intervene a maxim max3232 probably.

/*
 Switch statement  with serial input
 http://www.arduino.cc/en/Tutorial/SwitchCase2
 */
//SOTIRIS DESCRIPTION
//UPDATE ON 26/11/2013 - I change all the switch commands to letters and keep numbers only for timings, so I can read with parseint without the need of character identifier.
/* 
 STRING ON SCREEN   :12345608
 SERIAL IN RECEIVED :78341209
 PORTS DIGITAL CTRL :674723--
 */


// Definition of interrupt names
#include < avr/io.h >
// ISR interrupt service routine

// constants won't change. They're used here to
// set pin numbers:
const int sensePin = 20;     // the number of the sensor pin
const int triggerpin =  52;      // the number of the trigger pin

//SETTINGS FOR THE DELAY ENGAGEMENT
int delays[]={100,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,999};
int indexdel=9;
int uclost = 300;
int konter;
char inByte[4];


//PNEUMATIC VALVE CONTROLS

void setup()
{
  // initialize serial communication:
  Serial3.begin(9600);
  
  pinMode(triggerpin,OUTPUT);
  //  Serial.begin(9600);

  // initialize the LED pins:
  for (int thisPin = 2; thisPin <= 7; thisPin++)
  { 
    pinMode(thisPin, OUTPUT);      
  }
  pinMode(sensePin, INPUT);
  
  digitalWrite(sensePin,HIGH);
//  digitalWrite(triggerpin,LOW);
  // pinMode(ledPin, OUTPUT);
  //  attachInterrupt(3, blink, CHANGE);
}

void resetbyte()
{
  inByte[1]=0;
  inByte[2]=0;
  inByte[3]=0;
  inByte[4]=0; 
}

void empty()
{
    for (int lala = 1; lala <=2; lala++)
    {
    Serial3.read();
    }
}

void loop() 
{
  if (Serial3.available() > 0)
    {
    inByte[1] = Serial3.read();
    }
    // do something different depending on the character received.  
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For
    // example 'a' = 97, 'b' = 98, and so forth:
   {
    switch (inByte[1]) 
    
    {

     case 'A':  
       {  
                 resetbyte();
        empty();
        digitalWrite(triggerpin, LOW);
        delay(100);
        digitalWrite(triggerpin, HIGH);

       }
     break;
      
     case 'X':    
       {
        Serial3.print('D');
        Serial3.println(delays[indexdel]);
        delay(5);
        resetbyte();
        empty();
       }
     break;
        
     case 'F' :    
       {
        digitalWrite(2, LOW);
        resetbyte();
        empty();
       }
     break;
    
     case 'G':    
       {
        digitalWrite(3, LOW);
        resetbyte();
        empty();
       }
     break;
    
     case 'D':    
       {
        digitalWrite(4, LOW);
        resetbyte();
        empty();
       }
     break;
    
     case 'E':    
        {
         digitalWrite(5, LOW);
         resetbyte();
         empty();
        }
     break;

     case 'B': 
        {   
         digitalWrite(6, LOW);
         delay(2000);
         digitalWrite(6, HIGH);
         resetbyte();
         empty();
        }
     break;
    
     case 'C':  
       {  
        digitalWrite(7, LOW);
        delay(2000);
        digitalWrite(7, HIGH);
        resetbyte();
        empty();
       }
     break;
     
     case 'I':  
      { 
      resetbyte();
      empty();
      // DISSOLUTION START POINT 
      digitalWrite(7, LOW); //
      delay(2000);
      digitalWrite(7, HIGH);
      delay(100);
      digitalWrite(6, LOW); // main valve put in position
      delay(2000);
      digitalWrite(6, HIGH); ///main valve put in position
      digitalWrite(3, LOW); // open low pressure valve
      digitalWrite(4, LOW);
      delay(500);
      digitalWrite(4, HIGH);// open and close vent valve for low     pressure
      delay(1000);
      digitalWrite(2,LOW); // high pressure
      delay(2000);
      // if sensePin=LOW;

      while(digitalRead(sensePin) != HIGH) { 
      } // do nothing - WARNING - THIS HANGS THE ARDUINO UNTIL DIGITAL TRIGGER SIGNAL RECEIVED. 
      digitalWrite(7,LOW); //valve position air pulse on
      delay(delays[indexdel]);
      digitalWrite(5,LOW); //Stabilising Pressure
      delay(50);
      //digitalWrite(2,HIGH);
      digitalWrite(triggerpin,LOW); //trigger pulse for NMR
      delay(100);
      digitalWrite(triggerpin,HIGH);
      delay(1250); //to add up for two seconds for the Valve
      digitalWrite(7,HIGH); //valve position air pulse off
      //this is where it is supposed to end, next is only for debugging
      //I can use multiple delays and having a pin in unchanged state.
      //With this trich I can use 2 delays of total time 2 second (time needed for the Pneumatic Valve Switch)
      //and alter the injection time delay (can vary between 0 - 2000ms).
      //The 2 delays can be preprogrammed values after optimisation and preselected in a new menu called "dissolution options").
      //
       }
      break;
    
      case 'H': 
      {   
      for (int thisPin = 2; thisPin <= 7; thisPin++)
      {
        digitalWrite(thisPin, HIGH);
      }
      resetbyte();
      empty();
      }
      break;
      
      case 'S':
      {
        int sot = Serial3.parseInt();
        empty();
        resetbyte();
        for (konter=0; konter<=17; konter++)
          {
            if (sot == delays[konter])
              {
                indexdel = konter;
              }
          }
      }
      break;
   
      default:
        {
      // turn all the LEDs off:
      //    for (int thisPin = 2; thisPin <= 7; thisPin++)
      //      {
      //        digitalWrite(thisPin, HIGH);
      //      }
         }
    }
  }
}