Problema serial monitor quando collego circuito esterno

Buongiorno a tutti,

ho creato con un Mega 2560 un piccolo circuito al fine di gestire un piccolo bioreattore per gas alimentato a 12 V in corrente continua (utilizzo un alimentatore da PC 220V-12V a 12A) che gestisce: due valvole Burkert (12V - 0,4 A) e una piccola pompa peristaltica (12V - 80mA) con un banco relé; un sensore pH della Atlas Scientific gestito da un EZO pH circuit Versione 5.0. Una pompa a gas (12V - 1A) tramite PWM usando un mosfet FQP30N06L e modificando il uno dei tre clock per usare una frequenza più alta (+ventolina 12V per tenere il mosfetfreddo).

lo sketch è diviso in cicli di 4 ore in modo che: attivi la pompa del gas (2,5 sec ON e 7,5 sec OFF ) di default , ogni 5 minuti prenda una lettura di pH, ogni 4 ore parta il ciclo di carico/scarico bioreattore con in ordine: apertura valvola, accensione pompa peristaltica, accensione seconda valvola (una alla volta non sovrapposti). Dopo di che il ciclo riparte.

Per poter tracciare le varie fasi e per prendere i dati in uscita del pHmetro faccio stampare dal Serial0, separati da ";" , le informazioni sul tempo e il tipo di operazione fatta (non uso un RTC esterno ma la libreria time.h).
Comunico poi con l'EZO di atlas scientific tramite UART sulla Serial2.

PROBLEMA

Quando ho provato lo sketch senza collegare nulla (solo il pHmetro) funziona tutto, ma nel momento in cui collego pompe e valvole, anche se lo sketch funziona perfettamente con i tempi giusti, il Serial monitor o un eventuale gestore delle COM (uso terminal.exe) non va; o meglio registra la prima operazione o al massimo le prime 4-5 e poi si blocca, mentre per il resto tutto funziona (timer, attivazione pompe e valvole coi tempi giusti).

Ho letto diverse QA nel forum ma non ne sono venuto a capo, ho provato ad usare diversi COM e ho anche provato ad alimentare il mega con l'alimentazione oltre che con l'USB, in quanto pensavo che non riuscisse a gestire il tutto... ma non cambia la storia.

Un dubbio che mi sorge è che ci siano interferenze data la vicinanza di motori a DC, e in qualche modo interferisca con la seriale, ma non mi spiego perché il resto continui a funzionare...

Vi lascio i link a dei componenti simili a quelli che ho in lab e un pdf con gli schemi dicollegamento elettrico a questo link di google drive.

Qui sotto invece lascio lo sketch.

Sketch

/***MADE FOR ARDUINO ATmega2560***/

#include <Time.h>                //used to track time (<50gg)
#include <TimeLib.h>             //used to track time (<50gg)
//#include <SoftwareSerial.h>      //we have to include the SoftwareSerial library, or else we can't comunicate with the sensor
//#define rx 2                     //define what pin rx is going to be.
//#define tx 3                     //define what pin Tx is going to be.



/*
  This code is divided into different functions, each of them make a measure/process of the bioreactor.
  The loop is 4 hours long and is repeted 6 times for day.
  From the PARAMETER BOX in the head space of the script there is the possiblity to change the most important parameters.
  This script allows pH measures which are recorded also providing date and time. The data otained can be imported in excel and can be separated by ";".
  Further more, if a pH measure is made after a liquid input (possible pH modification) it will print this information in the report to allow a better understand of the data.


  IMPORTANT!
  -Before to start the operation pH prob has to be calibrated. This script is made for pH EZO chip V 1.2
  -The total duration in milliseconds of the FWD cycle (Feeding of gas and liquid, and WithDrow) must be determine to corectly
   set all the variables (follow the FWD_time comments instruction below in the PARAMETER BOX).
  -The liquid temperature has to be specify to allow  correct pH measure, edit it in the PARAMETER BOX
  -All the variables in the information box has to be checked
  -Use a third serial monitor software to be able to record the data (eg Termilan.exe)




  PIN CONNECTION SUMMARY:
  pin 2:  connected to the tx of the EZP chip
  pin 3:  connected to the rx of the EZP chip
  pin 6:  gas pump for the recirculation to mosphet
  pin 9:  hydrogen valve for feeding rele
  pin 10: liquid feeding peristaltic pump rele
  pin 11: liquid wihdrow valve rele

*/


/*________________________PARAMETER BOX START_________________________*/

int  se = 0, mi = 00, ho = 00, da = 14, mo = 3, ye = 22; //set time in which the automatic reactor starts: se=seconds, mi=minute, ho=hour, da=day, mo=month, ye=year (only last 2 numbers, eg 2022=22) ::ATTENTION:: max time garantee is 49.7 days!

char pH_temperature[] = "36\r"; //::CHECK CODE::this parameter can be edit before to start the code. Insert the Temperature of the liquid to have more precise readings, do not dele \r!

const unsigned long gas_pump_ON_time = 2500;  //time of gas pump on during normal cycle
const unsigned long gas_pump_OFF_time = 7500; //time of gas pump off during normal cycle, can be adjust based on the pH and FWD cycle duration
int PWM_pump = 235;   //PWM which regulate the ml/min of the gas pump

const unsigned long CYCLE_HOUR = 4 * 60 * 60 * 1000L; //duration of a single cycle in milliseconds, here is in total 4 hours (6 times x day repeted)::ATTENTION:: KEEP L LETTER AFTER THE NUMBERS
const unsigned long FWD_time = 264000; //duration of all the feeding and withdrow sequence in one cycle in milliseconds, to determine it follow the instruction in the MAIN LOOP BOX

const unsigned long pH_reading_time = 300000; //MILLISECONDS time difference between each pH readings, 300000 = 5 min in millisecond

const unsigned long H2_feeding_time = 800; //duration of the hydrogen feeding (valve open) in milliseconds

const unsigned long liquid_feeding_time = 3509;  //duration of the liquid feeding (peristaltic pump on) in milliseconds

const unsigned long liquid_WD_time = 180000;   //duration of the liquid withdrow in milliseconds

/*_________________________PARAMETER BOX END___________________________*/




//PUMPS PINS
const int gas_pump = 8; //6 for position1, 7 for position 2, 8 for position 3
const int H2_valve = 9;
const int liquid_feed_valve = 10;
const int liquid_WD_valve = 11;

//TIME VARIABLES NOT TO BE EDIT
unsigned long t_pH = 0, dt_pH = 0, t_FWD = 0, dt_FWD = 0 ;
const unsigned long normal_time = CYCLE_HOUR - FWD_time ; //4h in milliseconds - FWD_time



//OTHER VARIABLES
const int enable_pH = 30;
char read_onepoint[] = "R,1\r";
boolean start_feeding = false;


//SENSOR VARIABLES
//SoftwareSerial Serial2(rx, tx); //define how the soft serial port is going to work.
char pH_data[30];
char computerdata[20];
byte received_from_computer = 0;
byte received_from_sensor = 0;
byte arduino_only = 0;
byte startup = 0;
float EC = 0;



//Declaration of the functions
void gas_rec();   //main cycle
void read_pH();   //main cycle
void H2_feed();       //FWD cycle
void liquid_feed();   //FWD cycle
void liquid_WD();     //FWD cycle




/*Declaration of the Serial monitor inputs*/

/*void serialEvent() {
  received_from_computer = Serial.readBytesUntil(13, computerdata, 20);
  computerdata[received_from_computer] = 0;
  Serial2.print(computerdata);
  Serial2.print('\r');

  }*/



/*Declaration of the Setup*/
void setup() {
  TCCR4B = TCCR4B & 0b11111000 | 0x01;    //set the pins 6, 7, 8 at higher PWM speed
  setTime(ho, mi, se, da, mo, ye);
  pinMode(enable_pH, OUTPUT);
  digitalWrite(enable_pH, LOW);
  Serial.begin(9600);
  Serial2.begin(9600);
  Serial2.print("C,0\r");
  Serial2.print("RESPONSE,0\r");
  Serial2.print(pH_temperature);



  pinMode(gas_pump, OUTPUT);
  pinMode(H2_valve, OUTPUT);
  pinMode(liquid_feed_valve, OUTPUT);
  pinMode(liquid_WD_valve, OUTPUT);


  digitalWrite(gas_pump, LOW);
  digitalWrite(H2_valve, HIGH);
  digitalWrite(liquid_feed_valve, HIGH);
  digitalWrite(liquid_WD_valve, HIGH);



  t_FWD = millis();
  t_pH = millis();
}



/*____________________________________________MAIN LOOP BOX starts____________________________*/
/*To make easier the FWD determination set the dime to 00:00:00*/
void loop() {
  
if (start_feeding == false) {   //made only after first start
    H2_feed();
    start_feeding = true;
  }

  dt_FWD = millis() - t_FWD;

  //Serial.print("Feeding start in: ");       //uncomment to determine FWD_time
  //digitalClockDisplay();                 //uncomment to determine FWD_time
  //Serial.println("");                     //uncomment to determine FWD_time


  if (dt_FWD > normal_time) {                 //comment to determine FWD_time
    H2_feed();
    delay(5000);
    liquid_feed();

    unsigned long dt_HyBa = 0;          //wait one minute to allow liquid to be static
    unsigned long HyBa_start = millis();
    while (dt_HyBa < 60000) {
      dt_HyBa = millis() - HyBa_start;
    }

    liquid_WD();
    delay(5000);

    gas_rec();
    delay(500);

    read_pH();

    t_pH = millis();
    t_FWD = millis();
  }                                       //comment to determine FWD_time

  //Serial.print("Feeding end in: ");       //uncomment to determine FWD_time
  //digitalClockDisplay();                 //uncomment to determine FWD_time
  //Serial.println("");                     //uncomment to determine FWD_time

  dt_pH = millis() - t_pH;

  if (dt_pH > pH_reading_time) {              //to determine FWD_time comment all the following lines (<-- included these)
    read_pH();
    t_pH = millis();
  }


  gas_rec();

  /*:::TEST AREA:::*/

//   Serial.println("ciao");
//     gas_rec();
//     delay(1000);
//     H2_feed();
//     delay(1000);
//     liquid_feed();
//     delay(1000);
//     liquid_WD();
//     delay(1000);
//     read_pH();

}

/*____________________________________________MAIN LOOP BOX  ends____________________*/


/*Declaration of the funtions*/


void gas_rec() {                            //cycle which regulates the normal gas recyrculation //ADD LED OPENING
  unsigned long dt_gas_pump_on = 0;
  unsigned long dt_gas_pump_off = 0;
  unsigned long t_gas_pump = millis();

  while (dt_gas_pump_on <= gas_pump_ON_time) {
    analogWrite(gas_pump, PWM_pump);
    dt_gas_pump_on = millis() - t_gas_pump;
  }
  digitalWrite(gas_pump, LOW);

  t_gas_pump = millis();
  while (dt_gas_pump_off <= gas_pump_OFF_time) {      //POSSIBLE TO INSERT THE INTERUPTION HERE FOR THE PWM REGULATION
    dt_gas_pump_off = millis() - t_gas_pump;
  }
}


/*:::::::::::::::::::::::::::::::::::::::::::::::::::::MAKE SOME INITIAL pH READING TO ALLOW STABILIZATION:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*::::::since pH is read while there is nothing else opened in terms of electrical things maybe is not influenced!::::::::::::::::::::::::::::::::::::::*/
void read_pH() {                                   //cycle which comand the pH reading
  Serial2.flush();
  /*int n = 0;                      //possible code to remove first ten readings
    while (n < 10) {
    Serial2.print("R,1\r");
    Serial2.flush();           //check if serial.flush() work to clean the serial port
    n++;
    }*/

  Serial2.print(read_onepoint);
  if (Serial2.available()) {                                             //  if (Serial2.available()>0) {
    received_from_sensor = Serial2.readBytesUntil('\r', pH_data, 30);
    pH_data[received_from_sensor] = 0;
    Serial.print("pH reading;");
    digitalClockDisplay();
    Serial.print(pH_data);

    if (dt_FWD > normal_time) {
      Serial.println("; made after fresh liquid addition");
    }
    else {
      Serial.println("");
    }
  }
}


void H2_feed() {                                    //cycle which comand the hydrogen valve opening
  /*Serial.print("Hydrogen feeding START;");
  digitalClockDisplay();
  Serial.println("");
  delay(1000);*/
  Serial.println("Hydrogen feed");

  unsigned long dt_H2_feed = 0;
  unsigned long t_H2_feed = millis();

  while (dt_H2_feed <= H2_feeding_time) {
    digitalWrite(H2_valve, LOW);
    dt_H2_feed = millis() - t_H2_feed;
  }
  digitalWrite(H2_valve, HIGH);

  /*delay(1000);
    Serial.print("Hydrogen feeding END;");
    digitalClockDisplay();
    Serial.println("");*/
}


void liquid_feed() {
  /*Serial.print("Liquid feeding START;");
    digitalClockDisplay();
    Serial.println("");//cycle which comand the liquid feeding peristaltic pump

    delay(1000);*/

  unsigned long dt_liquid_feed = 0;
  unsigned long t_liquid_feed = millis();

  while (dt_liquid_feed <= liquid_feeding_time) {
    digitalWrite(liquid_feed_valve, LOW);
    dt_liquid_feed = millis() - t_liquid_feed;
  }
  digitalWrite(liquid_feed_valve, HIGH);

  /*delay(1000);
    Serial.print("Liquid feeding END;");
    digitalClockDisplay();
    Serial.println("");*/

}

void liquid_WD() {
  /* Serial.print("Liquid withdrow START;");
    digitalClockDisplay();
    Serial.println("");

    delay(1000);*/

  unsigned long dt_liquid_WD = 0;
  unsigned long t_liquid_WD = millis();

  while (dt_liquid_WD <= liquid_WD_time) {
    digitalWrite(liquid_WD_valve, LOW);
    dt_liquid_WD = millis() - t_liquid_WD;
  }
  digitalWrite(liquid_WD_valve, HIGH);


  /*delay(1000);
    Serial.print("Liquid withdrow END;");
    digitalClockDisplay();
    Serial.println("");*/
}



void digitalClockDisplay() {    //time function
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(";");
  Serial.print(day());
  Serial.print("/");
  Serial.print(month());
  Serial.print("/");
  Serial.print(year());
  Serial.print(";");
}

void printDigits(int digits) {    //time function
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

ps: alcuni commenti sono destinati al mio collega che non sa programmare

Spero davvero mi possiate aiutare e di aver descritto il problema nel dettaglio. Ringrazio in anticipo chiunque mi dia anche il minimo supporto :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.