Go Down

Topic: A complete Arduino based timing controller system (Read 2829 times) previous topic - next topic

sotirisk

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.

https://link.springer.com/article/10.1007%2Fs00723-015-0680-5

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.
Tonto el que no entienda

zoomx


Kenneth2018

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

zoomx

You can find all the code in the supplementary material of the afforementioned publication,
can you have access to the paper?

Kenneth2018

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

sotirisk

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.

Code: [Select]
/*
 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);
      //      }
         }
    }
  }
}
Tonto el que no entienda

Go Up